Pondering about DateTime and it's Ticks…

Recently someone was able to convince me that there is no problem with using System.DateTime for the storage of localtimes (even if DST is in effect), because it works with Ticks and i bought into his base + offset story…. The following table explains his reasoning:

Utc Localtime Ticks (Localtime)
2007-10-27 23:59:59 2007-10-28 01:59:59 633291335990000000
+1 second 2007-10-28 02:00:00 633291336000000000
+2 seconds 2007-10-28 02:00:01 633291336010000000
+60 minutes 2007-10-28 02:59:59 633291371990000000
+60 minutes and 1 second 2007-10-28 02:00:00 633291332000000000
+60 minutes and 2 seconds 2007-10-28 02:00:01 633291332010000000

This reasoning gives you the impression that for each second 10000000 is added to the ticks.. However, this is faulty and in reality you get the following:

Utc Localtime Ticks (Localtime)
2007-10-27 23:59:59 2007-10-28 01:59:59 633291335990000000
+1 second 2007-10-28 02:00:00 633291336000000000
+2 seconds 2007-10-28 02:00:01 633291336010000000
+60 minutes 2007-10-28 02:59:59 633291371990000000
+60 minutes and 1 second 2007-10-28 02:00:00 633291336000000000
+60 minutes and 2 seconds 2007-10-28 02:00:01 633291336010000000

As you can see, instead of adding 10000000 to the ticks between 2007-10-27 00:59:59 and 01:00:00 in UTC there is a reduction of ticks in the localtime instead…. Because of this new DateTime(633291336000000000, DateTimeKind.Local) could represent both 2007-10-27 00:00:00 UTC and 2007-10-27 01:00:00 UTC… So if you want to keep out of trouble you’d better start storing your dates as UTC… If you don’t believe me, run the test yourself:

List<dateTime> localTimes = new List<dateTime>();

// start at 2007-10-27 23:59:59 UTC, which is 2007-28-10 01:59:59 localtime
DateTime utcBase = new DateTime(2007, 10, 27, 23, 59, 59, DateTimeKind.Utc);
localTimes.Add(utcBase.ToLocalTime());

// add 1 second to the base, which is 2007-28-10 02:00:00 localtime (first time)
localTimes.Add(utcBase.AddSeconds(1).ToLocalTime());

// add 2 seconds to the base, which is 2007-28-10 02:00:01 localtime (first time)
localTimes.Add(utcBase.AddSeconds(2).ToLocalTime());

// add 60 minutes to the base, which is 2007-28-10 02:59:59 localtime (first time)
localTimes.Add(utcBase.AddMinutes(60).ToLocalTime());

// add 60 minutes and 1 second to the base, which is 2007-28-10 02:00:00 localtime (second time)
localTimes.Add(utcBase.AddMinutes(60).AddSeconds(1).ToLocalTime());

// add 60 minutes and 2 second to the base, which is 2007-28-10 02:00:01 localtime (second time)
localTimes.Add(utcBase.AddMinutes(60).AddSeconds(2).ToLocalTime());

foreach (DateTime localTime in localTimes)
{
 Console.WriteLine(localTime.ToString("yyyy-MM-dd HH:mm:ss"));
 Console.WriteLine(localTime.Ticks);
 Console.WriteLine();
}
This entry was posted in Uncategorized and tagged . Bookmark the permalink.

2 Responses to Pondering about DateTime and it's Ticks…

  1. Joe says:

    I was not able to reproduce this problem. My results were consistent with the first table you present. Since I live in Florida, I used 5:59:59 on 10/28/2007 as the utcBase to get the same Ticks value you did for the first time. Other than that, I just copied and pasted your code.

  2. timvw says:

    That is because in EST the DaylightTime ends on 11/04/2007

    TimeZone.CurrentTimeZone.GetDaylightChanges(2007);

    So, if you start with
    DateTime utcBase = new DateTime(2007, 11, 4, 4, 59, 59, DateTimeKind.Utc); you will see the same effect…

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>