public void TestDateCompare()
        {
            Assert.That(dateUnspec.CompareTo(dateLocal) == 0);
            Assert.That(dateUnspec.Equals(dateLocal));
            Assert.AreEqual(dateUnspec.GetHashCode(), dateLocal.GetHashCode());
            Assert.That(dateLocal.CompareTo(dateUnspec) == 0);
            Assert.That(dateLocal.Equals(dateUnspec));
            Assert.AreEqual(dateLocal.GetHashCode(), dateUnspec.GetHashCode());

            DateTimeRange rangeUnspec = new DateTimeRange(dateUnspec, dateUnspec);
            DateTimeRange rangeLocal  = new DateTimeRange(dateLocal, dateLocal);

            Assert.That(rangeUnspec.CompareTo(rangeLocal) == 0);
            Assert.That(rangeUnspec.Equals(rangeLocal));
            Assert.AreEqual(rangeUnspec.GetHashCode(), rangeLocal.GetHashCode());
        }
        public void TestDateCompare()
        {
            Assert.That(dateUnspec.CompareTo(dateLocal) == 0);
            Assert.That(dateUnspec.Equals(dateLocal));
            Assert.AreEqual(dateUnspec.GetHashCode(), dateLocal.GetHashCode());
            Assert.That(dateLocal.CompareTo(dateUnspec) == 0);
            Assert.That(dateLocal.Equals(dateUnspec));
            Assert.AreEqual(dateLocal.GetHashCode(), dateUnspec.GetHashCode());

            DateTimeRange rangeUnspec = new DateTimeRange(dateUnspec, dateUnspec);
            DateTimeRange rangeLocal = new DateTimeRange(dateLocal, dateLocal);

            Assert.That(rangeUnspec.CompareTo(rangeLocal) == 0);
            Assert.That(rangeUnspec.Equals(rangeLocal));
            Assert.AreEqual(rangeUnspec.GetHashCode(), rangeLocal.GetHashCode());
        }
        /// <summary>
        /// Explicit comparison of DateTimeRanges to be used as a delegate.
        /// The result is the same as the DateTimeRange.CompareTo.
        /// </summary>
        /// <param name="x">The start date of the free busy</param>
        /// <param name="y">The granularity of the free busy in minutes</param>
        /// <returns>Negative, zero or possitive number if x is smaller, equal or bigger than y respectively</returns>
        public static int CompareRangesByStartThenEnd(
            DateTimeRange x,
            DateTimeRange y)
        {
            if ((x == null) && (y == null))
            {
                // If x is null and y is null, they are equal.
                return 0;
            }

            if (x == null)
            {
                // If x is null and y is not null, y is greater.
                return -1;
            }

            if (y == null)
            {
                // If x is not null and y is null, x is greater.
                return 1;
            }

            int result = x.Start.CompareTo(y.Start);

            if (result == 0)
            {
                result = x.End.CompareTo(y.End);
            }

            #if DEBUG
                Debug.Assert((result == 0) == (x.CompareTo(y) == 0) &&
                             (result > 0) == (x.CompareTo(y) > 0));
            #endif

            return result;
        }
        public void TestDateTimeCompare()
        {
            // (From MSDN) For objects A, B, and C, the following must be true:
            //
            // 0. By definition, any object compares greater than a null reference.
            //
            // 1. A.CompareTo(A) is required to return zero.
            //
            // 2. If A.CompareTo(B) returns zero, then B.CompareTo(A) is required to return zero.
            //
            // 3. If A.CompareTo(B) returns zero and B.CompareTo(C) returns zero,
            //    then A.CompareTo(C) is required to return zero.
            //
            // 4. If A.CompareTo(B) returns a value other than zero,
            //    then B.CompareTo(A) is required to return a value of the opposite sign.
            //
            // 5. If A.CompareTo(B) returns a value x that is not equal to zero,
            //    and B.CompareTo(C) returns a value y of the same sign as x,
            //    then A.CompareTo(C) is required to return a value of the same sign as x and y.
            //

            DateTimeRange r0 = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            DateTimeRange r0Copy1 = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            DateTimeRange r0Copy2 = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            DateTimeRange r1 = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z").ToUniversalTime(),
                DateTime.Parse("2007-07-01T06:16:11.000Z").ToUniversalTime());

            Assert.AreEqual(DateTimeKind.Local, r0.Start.Kind);
            Assert.AreEqual(DateTimeKind.Local, r0.End.Kind);

            Assert.AreEqual(DateTimeKind.Utc, r1.Start.Kind);
            Assert.AreEqual(DateTimeKind.Utc, r1.End.Kind);

            Assert.Greater(r0.CompareTo(null), 0); // 0.

            Assert.AreEqual(r0.CompareTo(r0), 0); // 1.
            Assert.AreEqual(r1.CompareTo(r1), 0); // 1.

            Assert.AreNotEqual(r0, r1);
            Assert.AreNotEqual(r0.CompareTo(r1), 0);
            Assert.AreNotEqual(r1.CompareTo(r0), 0);

            Assert.AreEqual(Sign(r0.CompareTo(r1)), -Sign(r1.CompareTo(r0))); // 4.

            Assert.AreEqual(r0.CompareTo(r0Copy1), 0);
            Assert.AreEqual(r0Copy1.CompareTo(r0), 0); // 2.
            Assert.AreEqual(r0.CompareTo(r0Copy2), 0);
            Assert.AreEqual(r0Copy2.CompareTo(r0), 0); // 2.
            Assert.AreEqual(r0Copy2.CompareTo(r0Copy1), 0); // 3.
            Assert.AreEqual(r0Copy1.CompareTo(r0Copy2), 0); // 3.

            // Get a basic range.
            DateTimeRange rAB = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            // Get two ranges that are bigger than the basic, because of the start or end.
            DateTimeRange rAPlusOneB = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:12.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            DateTimeRange rABPlusOne = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:12.000Z"));

            // Do the same for the two derived ranges
            // This produces 3 new ranges, because the A+1B+1 is shared
            DateTimeRange rAPlusTwoB = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:13.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            DateTimeRange rAPlusOneBPlusOne = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:12.000Z"),
                DateTime.Parse("2007-07-01T06:16:12.000Z"));

            DateTimeRange rABPlusTwo = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:13.000Z"));

            Assert.Less(rAB.CompareTo(rAPlusOneB), 0);
            Assert.Less(rAB.CompareTo(rABPlusOne), 0);

            Assert.Greater(rAPlusOneB.CompareTo(rAB), 0); // 3.
            Assert.Greater(rABPlusOne.CompareTo(rAB), 0); // 3.

            Assert.Less(rAPlusOneB.CompareTo(rAPlusOneBPlusOne), 0);
            Assert.Less(rAPlusOneB.CompareTo(rAPlusTwoB), 0);

            Assert.Greater(rAPlusOneBPlusOne.CompareTo(rAPlusOneB), 0); // 3.
            Assert.Greater(rAPlusTwoB.CompareTo(rAPlusOneB), 0);        // 3.

            Assert.Less(rABPlusOne.CompareTo(rAPlusOneBPlusOne), 0);
            Assert.Less(rABPlusOne.CompareTo(rABPlusTwo), 0);

            Assert.Greater(rAPlusOneBPlusOne.CompareTo(rABPlusOne), 0); // 3.
            Assert.Greater(rABPlusTwo.CompareTo(rABPlusOne), 0);        // 3.

            Assert.Less(rAB.CompareTo(rAPlusTwoB), 0);        // 5.
            Assert.Less(rAB.CompareTo(rAPlusOneBPlusOne), 0); // 5.
            Assert.Less(rAB.CompareTo(rABPlusTwo), 0);        // 5.

            Assert.Greater(rAPlusTwoB.CompareTo(rAB), 0);        // 3.
            Assert.Greater(rAPlusOneBPlusOne.CompareTo(rAB), 0); // 3.
            Assert.Greater(rABPlusTwo.CompareTo(rAB), 0);        // 3.
        }
        public void TestDateTimeCompare()
        {
            // (From MSDN) For objects A, B, and C, the following must be true:
            //
            // 0. By definition, any object compares greater than a null reference.
            //
            // 1. A.CompareTo(A) is required to return zero.
            //
            // 2. If A.CompareTo(B) returns zero, then B.CompareTo(A) is required to return zero.
            //
            // 3. If A.CompareTo(B) returns zero and B.CompareTo(C) returns zero,
            //    then A.CompareTo(C) is required to return zero.
            //
            // 4. If A.CompareTo(B) returns a value other than zero,
            //    then B.CompareTo(A) is required to return a value of the opposite sign.
            //
            // 5. If A.CompareTo(B) returns a value x that is not equal to zero,
            //    and B.CompareTo(C) returns a value y of the same sign as x,
            //    then A.CompareTo(C) is required to return a value of the same sign as x and y.
            //

            DateTimeRange r0 = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            DateTimeRange r0Copy1 = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            DateTimeRange r0Copy2 = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            DateTimeRange r1 = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z").ToUniversalTime(),
                DateTime.Parse("2007-07-01T06:16:11.000Z").ToUniversalTime());

            Assert.AreEqual(DateTimeKind.Local, r0.Start.Kind);
            Assert.AreEqual(DateTimeKind.Local, r0.End.Kind);

            Assert.AreEqual(DateTimeKind.Utc, r1.Start.Kind);
            Assert.AreEqual(DateTimeKind.Utc, r1.End.Kind);

            Assert.Greater(r0.CompareTo(null), 0); // 0.

            Assert.AreEqual(r0.CompareTo(r0), 0);  // 1.
            Assert.AreEqual(r1.CompareTo(r1), 0);  // 1.

            Assert.AreNotEqual(r0, r1);
            Assert.AreNotEqual(r0.CompareTo(r1), 0);
            Assert.AreNotEqual(r1.CompareTo(r0), 0);

            Assert.AreEqual(Sign(r0.CompareTo(r1)), -Sign(r1.CompareTo(r0))); // 4.

            Assert.AreEqual(r0.CompareTo(r0Copy1), 0);
            Assert.AreEqual(r0Copy1.CompareTo(r0), 0);      // 2.
            Assert.AreEqual(r0.CompareTo(r0Copy2), 0);
            Assert.AreEqual(r0Copy2.CompareTo(r0), 0);      // 2.
            Assert.AreEqual(r0Copy2.CompareTo(r0Copy1), 0); // 3.
            Assert.AreEqual(r0Copy1.CompareTo(r0Copy2), 0); // 3.

            // Get a basic range.
            DateTimeRange rAB = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            // Get two ranges that are bigger than the basic, because of the start or end.
            DateTimeRange rAPlusOneB = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:12.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            DateTimeRange rABPlusOne = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:12.000Z"));

            // Do the same for the two derived ranges
            // This produces 3 new ranges, because the A+1B+1 is shared
            DateTimeRange rAPlusTwoB = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:13.000Z"),
                DateTime.Parse("2007-07-01T06:16:11.000Z"));

            DateTimeRange rAPlusOneBPlusOne = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:12.000Z"),
                DateTime.Parse("2007-07-01T06:16:12.000Z"));

            DateTimeRange rABPlusTwo = new DateTimeRange(
                DateTime.Parse("2007-06-30T05:16:11.000Z"),
                DateTime.Parse("2007-07-01T06:16:13.000Z"));

            Assert.Less(rAB.CompareTo(rAPlusOneB), 0);
            Assert.Less(rAB.CompareTo(rABPlusOne), 0);

            Assert.Greater(rAPlusOneB.CompareTo(rAB), 0); // 3.
            Assert.Greater(rABPlusOne.CompareTo(rAB), 0); // 3.

            Assert.Less(rAPlusOneB.CompareTo(rAPlusOneBPlusOne), 0);
            Assert.Less(rAPlusOneB.CompareTo(rAPlusTwoB), 0);

            Assert.Greater(rAPlusOneBPlusOne.CompareTo(rAPlusOneB), 0); // 3.
            Assert.Greater(rAPlusTwoB.CompareTo(rAPlusOneB), 0);        // 3.

            Assert.Less(rABPlusOne.CompareTo(rAPlusOneBPlusOne), 0);
            Assert.Less(rABPlusOne.CompareTo(rABPlusTwo), 0);

            Assert.Greater(rAPlusOneBPlusOne.CompareTo(rABPlusOne), 0); // 3.
            Assert.Greater(rABPlusTwo.CompareTo(rABPlusOne), 0);        // 3.

            Assert.Less(rAB.CompareTo(rAPlusTwoB), 0);                  // 5.
            Assert.Less(rAB.CompareTo(rAPlusOneBPlusOne), 0);           // 5.
            Assert.Less(rAB.CompareTo(rABPlusTwo), 0);                  // 5.

            Assert.Greater(rAPlusTwoB.CompareTo(rAB), 0);               // 3.
            Assert.Greater(rAPlusOneBPlusOne.CompareTo(rAB), 0);        // 3.
            Assert.Greater(rABPlusTwo.CompareTo(rAB), 0);               // 3.
        }