Tim Van Wassenhove home

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();
}