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?

- 7,510
- 6
- 35
- 43
-
I think I might have created confusion with my answer below. Is this Compact Framework, or no? While we're at it, what version of the .NET Framework are you using? – lance Jun 05 '09 at 19:44
-
I'm using .NET 2.0, not the Compact Framework. – Shane Fulmer Jun 05 '09 at 19:47
4 Answers
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?

- 16,092
- 19
- 77
- 136
-
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 Jun 05 '09 at 19:50
-
Does TimeZone.CurrentTimeZone.ToLocalTime(savedDate) give a different result (http://stackoverflow.com/questions/179940/c-convert-gmt-time-to-local-time/180105#180105)? – lance Jun 05 '09 at 19:52
-
1"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 Jun 05 '09 at 19:59
-
That is helpful information - do you know off hand if DST works around that when the change actually occurs? – Shane Fulmer Jun 05 '09 at 20:01
-
-
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 Jun 05 '09 at 20:07
-
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 Jun 05 '09 at 20:09
-
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 Jun 05 '09 at 20:10
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.)

- 1,421,763
- 867
- 9,128
- 9,194
-
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 Jun 05 '09 at 19:50
-
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 Jun 05 '09 at 19:52
-
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 Jun 05 '09 at 19:57
-
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 Jun 05 '09 at 20:23
-
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 Jun 05 '09 at 20:41
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();

- 122,218
- 32
- 205
- 338
I have discovered that some .Net CF 2.0 builds do not properly do time translations between UTC and local time. The issues surround the change that occurred in US timezone several years ago.
The symptom is that DST appears to not be considered to go into effect until April (old rule) rather than March (new rule). Presumably, there is also a problem on the back-end of the DST change (October/November).
As yet I have not found information about what might be the minimum build needed for the translation to work correctly.
Note the this is NOT fixed by applying the operating system DST fix (which, obviously, should also be installed). It is completely intrinsic to CF as far as I can tell. I've not tried every combination, but just be careful.
If you want accurate translations in CF, you have only two options:
do the conversion yourself (very complex, rigid, and error-prone).
ensure you have the necessary .Net and OS patches on the device so that translations are accurate.
You might also be able to find a class library that will work for you. One promising class was World Clock / Code Project), but, unfortunately it relies on registry information not available in CF. Thus, it's not directly portable to CF.
And then finally, any roll-your-own solution will require on having time zone information available (UTC offsets, DST on/off dates, etc). and accurate at all times.
Sorry for the bad news.

- 51
- 1
- 2