Question

I encountered what may be a leap year in .NET's DateTime handling, specifically ToLocalTime(). Here's some code which reproduces the problem (I'm in the Pacific time zone):

DateTime dtStartLocal = DateTime.Parse("2009-02-28T23:00:00.0-08:00");
DateTime dtEndLocal = dtStartLocal.AddYears(3);
DateTime dtStartUtc = dtStartLocal.ToUniversalTime();
DateTime dtEndUtc = dtStartUtc.AddYears(3);
DateTime dtEndLocal2 = dtEndUtc.ToLocalTime();
DateTime dtStartLocal2 = dtStartUtc.ToLocalTime();
Console.WriteLine("START: 1={0}, 2={0}", dtStartLocal, dtStartLocal2);
Console.WriteLine("END  : 1={0}, 2={1}", dtEndLocal, dtEndLocal2);
Console.ReadLine();

The output is:

START: 1=2/28/2009 11:00:00 PM, 2=2/28/2009 11:00:00 PM
END : 1=2/28/2012 11:00:00 PM, 2=2/29/2012 11:00:00 PM

Notice the variable which I did ToUniversalTime().AddYears(3).ToLocalTime() is different than just AddYears(3), it's one day ahead.

Has anyone encountered this? If this is expected, can someone explain the logic behind it?

NOTE: Yes, the best approach is to work entirely in UTC and not flip flop between them. This isn't something which is effecting me, but a peculiarity I encountered. Essentially I misunderstood how AddYears() worked and now I can see why it's doing what it's doing (see my selected answer below).

Was it helpful?

Solution

I think that this is working correctly.

DateTime dtStartUtc = dtStartLocal.ToUniversalTime();

PST is UTC-8. Therefore, this converts the time to March 1, 2009, 07:00:00.

DateTime dtEndUtc = dtStartUtc.AddYears(3);

This adds three years to the previous time, putting it at March 1, 2012, 07:00:00.

DateTime dtEndLocal2 = dtEndUtc.ToLocalTime();

This converts the end time back to PST, which would be February 29, 2012, 11:00:00.

I'd say this is just a side affect of converting between local and UTC time.

OTHER TIPS

Print the timezone/correction factor. When you do the .ToUniversialTime() it essentially adds the 8 hours from your original time ("-08:00"), which would put it at 11:00 the next day starting from 23:00 hours February 28th. So when you add 3 years to it, it's the 11:00 AM on the 29th. Had you done 2 years, it would have been March 1st, it has nothing to do with the leap year.

This behaviour isn't incorrect, as far as I can tell. When you convert the local time to UTC it effectively pushes it into the next day; March 1st. When you add three years, it stays as March 1st. Convert it back to local time and it rolls back to the previous day, which because 2012 is a leap year, is February 29th.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top