none
DateTime conversion to UTC with DayLight Saving

    Question


  • I have a problem converting a provided DateTime to  UTC DateTime with day light saving rules. The Rules for Day light saving for US Eastern Time were changed in 2007.

    Rules Before 2007

    first Sunday in April (April 2, 2006), and changed back to standard time on the last Sunday in October (October 29, 2006).


    Rules After 2007

    second Sunday of March (March 11, 2007), which was three weeks earlier than in the past, and it ended on the first Sunday of November (November 4, 2007)

    Now when i convert my DateTime which are before 2007 to Universal time using the function myDate.ToUniversalTime() it applys the rules that are after 2007. i.e. The Date "April 01 2005" should be converted as "April 01 2005 05:00 AM" but it converts with 4 hour diffrence i.e. "April 01 2005 04:00 AM" which is not correct according to the day light saving rules before 2007.

    Now older DateTime which are between March and April , October and November (The diffrence between the two rules) are having +1 or -1 hour diffrence which is not correct according to the Day Light Saving Rules.

    I am using .net Framework 2.0

    I want to know is there any solution for this problem in the .net framwork class libraries or is the function ToUniversalDate() applys the rules for day light saving according to the changes or is there any patch from Microsoft which enables the .net framework to apply the day light saving rules accordingly.

    Thanks in advance for the help
    • Edited by Adeel Sethi Wednesday, October 22, 2008 7:32 AM
    Wednesday, October 22, 2008 7:29 AM

Answers

  • .NET 3.5 added the TimeZoneInfo class.  This class provides a history of TimeZone information for specific time zones around the world. With the exception of the fact that the US States doing as they pleased between 1945 and 1966, you can get general timezone information, with a conversion by calling something like the following code:

    TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time").GetUtcOffset(new DateTime(2005, 3, 25)); // yields -5 hours  
    TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time").GetUtcOffset(new DateTime(2008, 3, 25)); // yields -4 hours  
     

    There's a plethora of information regarding time zone shifts in this class. If you upgrade your code to 3.5 you could use it, along with all the other neat functionality that 3.5 has to offer.

    Best of luck.


    David Morton - http://blog.davemorton.net/

    Wednesday, October 22, 2008 2:06 PM

All replies

  • Neither .NET nor Windows keep a database that contains a history of DST rules.  That would be a pretty large database, especially since it would have to be localized.  In the US, states did as they pleased between 1945 and 1966.  Not practical, thus current DST rules are simply applied to previous years.  Not sure where you hang your hat, but I doubt it is different there.  You'll have to write custom code to convert.
    Hans Passant.
    Wednesday, October 22, 2008 10:45 AM
  • .NET 3.5 added the TimeZoneInfo class.  This class provides a history of TimeZone information for specific time zones around the world. With the exception of the fact that the US States doing as they pleased between 1945 and 1966, you can get general timezone information, with a conversion by calling something like the following code:

    TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time").GetUtcOffset(new DateTime(2005, 3, 25)); // yields -5 hours  
    TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time").GetUtcOffset(new DateTime(2008, 3, 25)); // yields -4 hours  
     

    There's a plethora of information regarding time zone shifts in this class. If you upgrade your code to 3.5 you could use it, along with all the other neat functionality that 3.5 has to offer.

    Best of luck.


    David Morton - http://blog.davemorton.net/

    Wednesday, October 22, 2008 2:06 PM
  • Hi,

    Although this post was started a long time back, I came across similar issue and I used the following code snippet to resolve it.

    public static double GetTimeZoneDeltaOffUTC(string clientTimeZoneId, DateTime? dateTime = null)
        {
          // TimeZoneInfo instance for the given clientTimeZoneId.
          System.TimeZoneInfo client = System.TimeZoneInfo.FindSystemTimeZoneById(clientTimeZoneId);
    
          // Get the standard UTC offset (Daylight saving adjustment not included as Date and Time aspect is not factored in to calculate the difference).
          double deltaInMinutes = client.BaseUtcOffset.TotalMinutes;
    
          // Check if user has specified DateTime to cater for Daylight saving time.
          if (dateTime.HasValue)
          {
            // Create a new instance of Date with Unspecified Kind.
            DateTime newDate = new DateTime(dateTime.Value.Year, dateTime.Value.Month, dateTime.Value.Day,
              dateTime.Value.Hour, dateTime.Value.Minute, dateTime.Value.Second, DateTimeKind.Unspecified);
    
            // Get total Ticks for Daylight Saving offset
            deltaInMinutes += (from rule in client.GetAdjustmentRules()
                      where rule.DateStart <= dateTime && rule.DateEnd >= dateTime
                      select rule.DaylightDelta.TotalMinutes).Sum();
          }
    
          return deltaInMinutes;
        }
    

    This method takes in a TimeZone name and a date. It then gets the difference between UTC and the given timezone. Then it checks if the give date falls in DST, if it does it finds the difference and adds it to the delta.

    Thus one gets the actual Converted date, for the specified TimeZone and the given date.

    • Proposed as answer by Hariraj Wednesday, April 13, 2011 5:11 AM
    Tuesday, April 12, 2011 1:14 PM