2

All of our date/time data in our database is stored in UTC time. I'm trying to write a function to convert that UTC time into the user's preferred time zone (they can select their timezone in their profile so it has NOTHING to do with local settings on their computer and everything to do with which timezone they have selected from a dropdown of available choices.

This function is in the context of a DevExpress AspxGridView event (the third party control is not relevant to the question but I thought I'd mention it):

DateTimeOffset utcTime = (DateTimeOffset)e.Value;

TimeZoneInfo destTimeZone = Helper.GetTimeZoneInfo();

DateTime modifiedDate = TimeZoneInfo
    .ConvertTimeFromUtc(utcTime.DateTime, destTimeZone);

e.DisplayText = String.Format("{0} {1}", 
                              modifiedDate.ToString("g"), 
                              destTimeZone.Abbreviation());

Helper.GetTimeZoneInfo() simply returns a TimeZoneInfo class that corresponds to the one the user selected, or defaults to "Pacific Standard Time" if they have not chosen one.

This generally works fine until I switch my system clock (which this server is running on) from today (which is Oct. 14, a DST date) to something like January 11, which is NOT DST.

The time seems to always be displayed in DST (i.e. always a 7 hour offset). No matter what I do with my system clock, I can't get the time to adjust for the extra hour.

For example, when I have my timezone set to Pacific Standard Time, for UTC time 10-10-2011 20:00:00, it is always displaying this time:

10-10-2011 13:00:00 (the DST time, offset of -7).

During non-Daylight Savings dates (standard), the time should be:

10-10-2011 12:00:00 (offset of -8).

What am I missing?

Dennis Traub
  • 50,557
  • 7
  • 93
  • 108
Scott
  • 13,735
  • 20
  • 94
  • 152
  • Related question: http://stackoverflow.com/questions/2532729/daylight-saving-time-and-timezone-best-practices – Oded Oct 14 '11 at 15:19
  • It sounds like you should be able to demonstrate this in a short but complete console application - that would make it easier for others to help you. Can you edit your question with a suitable example? What is the Offset in the `DateTimeOffset` you've retrieved? I note that you're currently throwing it away, which isn't ideal. – Jon Skeet Oct 14 '11 at 15:19
  • (Oh, and if you're interested in investigating whether [Noda Time](http://noda-time.googlecode.com) would make your life simpler here, I'd love to help you :) – Jon Skeet Oct 14 '11 at 15:20
  • 1
    What is the value of **e.Value** in both cases? – Security Hound Oct 14 '11 at 15:21
  • I sort of indirectly mentioned that at the bottom, when I used the example of 10-10-2011 20:00:00. This would represent what is in e.Value. – Scott Oct 14 '11 at 15:23

2 Answers2

1

The converted local time of a UTC time is always based on the time zone info for that UTC time... not for whatever the current time happens to be.

That is, the PST offset on Oct 10, 2011 UTC is always -7. It doesn't matter what date you are doing the conversion on.

...Or am I misunderstanding what you are asking?

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
0

You might have a look at the e.Value.

Is the DateTimeKind for it set to DateTimeKind.Utc or is it DateTimeKind.Unspecified

If it is Unspecified, the conversion will not work correctly.

One cannot set the Kind directly. The best I have come up with is something along the lines of

// the value off the DB, but Kind is unspecified
var fromDb = new DateTime(1999,31,12)         

// convert it to a Utc version of the same date
var fromDbInUtc = new DateTime(fromDb.Ticks, DateTimeKind.Utc)

var destTimeZone = Helper.GetTimeZoneInfo();     

var local = TimeZoneInfo.ConvertFromUtc(fromDbInUtc, destTimeZone);  

Hope this helps,

Alan.

AlanT
  • 3,627
  • 20
  • 28