Quirks of .NET DateTime type

It looks like subtracting dates in .NET is done purely mechanically, ignoring such subtleties as time zones or daylight savings time.

In particular, the UTC flag is ignored when subtracting dates. E.g. if you subtract 2008/11/22 13:15 UTC from 2008/11/22 13:15 local, you get zero hours difference in any time zone.

Similarly, daylight savings time is ignored. In US Eastern time zone 1:59AM on March 9, 2008 was immediately followed by 3:00AM: the clock had been moved forward by one hour. However, if you subtract those two dates, you will get a 61 minute difference.

Converting to UTC helps: the above dates give 1 minute difference when converted to UTC. This, however, means that the difference between your dates may change merely because you converted them to another time zone. This is bound to cause funny corner cases in some programs.

Here is the code that demonstrates some of the above:


using System;
using NUnit.Framework;

namespace DateDifference
{
    [TestFixture]
    public class DateDiff
    {
        [Test]
        public void UtcFlagIgnored()
        {
            DateTime d1 = new DateTime(2008, 11, 22, 13, 15, 0, DateTimeKind.Local);
            DateTime d2 = new DateTime(2008, 11, 22, 13, 15, 0, DateTimeKind.Utc);

            Assert.AreEqual(0, (d2 - d1).TotalHours);
        }

        [Test]
        public void DstIgnored()
        {
            DateTime d1 = new DateTime(2008, 3, 9, 1, 59, 0, DateTimeKind.Local);
            DateTime d2 = new DateTime(2008, 3, 9, 3, 0, 0, DateTimeKind.Local);

            Assert.AreEqual(61.0, (d2 - d1).TotalMinutes);
        }

        [Test]
        public void DstUsedInUtc()
        {
            DateTime d1 = new DateTime(2008, 3, 9, 1, 59, 0, DateTimeKind.Local);
            DateTime d2 = new DateTime(2008, 3, 9, 3, 0, 0, DateTimeKind.Local);

            DateTime u1 = d1.ToUniversalTime();
            DateTime u2 = d2.ToUniversalTime();

            Assert.AreEqual(1.0, (u2 - u1).TotalMinutes);
        }
   }
}

Leave a Reply

Your email address will not be published. Required fields are marked *