Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DateTime.ToLocalTime() in winter/summer time

Tags:

c#

.net

datetime

I am using DateTime.ToLocalTime() to convert dates from UTC to local time. My time zone is GMT+1(Belgrade, Budapest, Lubjna...), it is set properly in Windows Settings (XP).

Last weekend in our time zone we changed to winter time to summer time, it means, we set back local time by one hour.

As I see ToLocalTime method behaves strange from that moment. When I use it to convert dates that are after this winter time change, it works great, like this:

var utcDate2 = new DateTime(2011, 11, 2, 9, 0, 0,DateTimeKind.Utc);

utcDate1.ToLocalTime() value is: 2011.11.02. 10:00:00 it is correct

Burt when I want to convert a date before this change (e.g. a date from summer time) it gives back a bad value like this:

var utcDate1 = new DateTime(2011, 10, 23, 9, 0, 0,DateTimeKind.Utc);

utcDate2.ToLocalTime() value is: 2011.10.23. 10:00:00 it is incorrect It should be 2011.10.23. 11:00:00

What should I do to get correct values? How should I use ToLocalTime that also adjust winter/summer time?

like image 709
Tom Avatar asked Nov 02 '11 11:11

Tom


2 Answers

My guess is that the time zone data on your system may be out of date - or it's due to the limitation jsobo mentioned.

One option you might want to (cautiously) pursue is using my date/time API, Noda Time. This has conversion to/from DateTime so you could use DateTime elsewhere in your code, although obviously I believe your code would be clearer if you used Noda Time throughout :)

Noda Time isn't "v1.0-ready" yet, but mostly because of a few missing features. Whether you're willing to take the risk of a non-v1.0 open source project or not is up to you, of course, but I'd be very happy to help with any issues you run into. (I'm really trying to find real-life use cases, so if there are any missing features you need, I may well be able to implement them in anticipation of others needing the same thing.)

Noda Time uses the zoneinfo time zone database, not the one built into Windows, so it shouldn't have the same issues.

To check, you'd use code like this:

DateTimeZone belgradeZone = DateTimeZone.ForId("Europe/Belgrade"); // Or whatever
// Alternatively...
DateTimeZone localZone = DateTimeZone.SystemDefault;
ZonedDateTime utc = new ZonedDateTime(2011, 10, 23, 9, 0, 0, DateTimeZone.Utc);
ZonedDateTime belgrade = new ZonedDateTime(utc.ToInstant(), belgradeZone);
Console.WriteLine(belgrade.LocalDateTime);
like image 36
Jon Skeet Avatar answered Sep 18 '22 02:09

Jon Skeet


http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx

On Windows XP systems, the ToLocalTime method recognizes only the current adjustment rule when converting from UTC to local time. As a result, conversions for periods before the current adjustment rule came into effect may not accurately reflect the difference between UTC and local time.

So you will have to find another way to figure it out.

like image 190
John Sobolewski Avatar answered Sep 19 '22 02:09

John Sobolewski