tags:

views:

225

answers:

3

I'm working on an application that needs to run 24H a day, and am working on correctly implementing support for DST. All times are currently stored in UTC, but I'm having issues when I try to display in local time. Right now I'm using savedDate.ToLocalTime() to convert from DB values to local time for display. This seems to be working fine, except for when I change the time zone information in an effort to test DST. If I modify the timezone on the client pc, the display doesn't update with the new time zone. Is there a better way to test DST, or is my conversion to local time incorrect for this scenario?

+1  A: 

I remember reading, perhaps regarding the Compact Framework, about .NET not being the most reliable when it comes to reporting about DST. More reliable was getting the current time in local time and UTC, and then determining (and using in future adjustments) the difference yourself. That seems like a horrible route to go if it's not really necessary. I'll see if I can find a reference backing up what I think I remember.

What are you doing, exactly, to change the timezone on the workstation?

lance
I'm changing the time zone on my system clock from Eastern Time to Atlantic Time. This is in an effort to test DST by keeping my local box's UTC time the same, but having it's local time change.
Shane Fulmer
Does TimeZone.CurrentTimeZone.ToLocalTime(savedDate) give a different result (http://stackoverflow.com/questions/179940/c-convert-gmt-time-to-local-time/180105#180105)?
lance
It gives me the same result.
Shane Fulmer
"Yes, the current time zone is cached. You would have to call System.Globalization.CultureInfo.ClearCachedData() to reset it." (http://stackoverflow.com/questions/296918/net-datetime-now-returns-incorrect-time-when-time-zone-is-changed/297189#297189) -- Perhaps that's helpful?
lance
That is helpful information - do you know off hand if DST works around that when the change actually occurs?
Shane Fulmer
Works around that? I don't follow.
lance
Sorry, I should have been more clear. I think I will have to test it to know for sure, but now I'm wondering if the change to DST (in October and April) works the same way as a time zone change. I guess the question is whether or not ToLocalTime will return the updated DST time.
Shane Fulmer
I would certainly expect it to, give perhaps this caching issue. Perhaps Jon's "just before" changes are the right test now. Don't change the timezone -- just change the time... to see how .NET reacts to an honest DST change.
lance
I think this answers my question: "If the local time zone observes daylight saving time, ToLocalTime applies the current adjustment rule to time when performing the conversion." from (http://msdn.microsoft.com/en-us/library/system.timezone.tolocaltime(VS.100).aspx). I guess I need a different way to test it.
Shane Fulmer
I will try that - thanks so much for your help!
Shane Fulmer
+1  A: 

Hmm. Do you expect to actually have to change time zone while the app is running? I wouldn't be surprised if the framework cached it after it's first fetched.

I would set the time zone on the device, change the time to "just before the change to DST", run the app and check that it's reporting times correctly. Then change the time to "just before the change out of DST".

Bear in mind that depending on your device and the age of its time zone database, it may not know about the change to DST in the US a few years ago. (Ah, time zones. Gotta love 'em.)

Jon Skeet
Well the issue is not necessarily changing the timezone while the app is running, that's just my way to try to test DST (is there a better way?). But for some reason it seems like it is cached so that when I use ToLocalTime it is still pulling the time from the old timezone.
Shane Fulmer
My point is that if changing the time zone isn't something you need to worry about in real life, but it messes up your testing, then don't do it in your testing :) I know it's a pain to stop the app, change the settings, restart it, wait for an hour and a half (so you go over the complete transition period) and then change it again etc, but I *suspect* it'll be easier than fiddling with the code to avoid the caching issue. Of course there could be an easy solution about to be posted :)
Jon Skeet
I agree that it would be easy to stop the app and reload so that it gets the correct time, but that's not feasible for this application. It needs to run through DST unfortunately.
Shane Fulmer
I think you misunderstood me. When I say "time zone" I mean something like "Europe/London", which is in UTC in Winter and UTC+1 for summer. You leave it like that and the DST just changes automatically. The time zone itself doesn't change just because the current offset from UTC does :)
Jon Skeet
Right, I understand that the timezone doesn't change when DST changes. I just wasn't sure if ToLocalTime was going to take that into account. Thank you for you testing scenario, for some reason I didn't think of that. :)
Shane Fulmer
+1  A: 

If you retrieve a DateTime value from a database, you will generally get a DateTime with the Kind property set to DateTimeKind.Unspecified. Basically because any database-specific DateTime types I'm aware of (e.g. SqlDateTime) don't include timezone information.

If you then try to "convert" this to local time using savedDate.ToLocalTime(), you'll get back the same DateTime value that was stored, without any conversion.

What you need to do is indicate that the saved date is in UTC before performing the conversion, something like:

DateTime savedDateTime = (DateTime) reader["SomeDateTimeColumn"];

// Convert from unspecified to UTC
DateTime utcDateTime = savedDateTime.SpecifyKind(savedDateTime, DateTimeKind.Utc);
...
// Convert from UTC to local
DateTime localDateTime = utcDateTime.ToLocalTime();
Joe