Naveen's Weblog

Bridge to future

GetDaylightChanges with TimeZoneInfo

Posted by codingsense on February 3, 2010


Hi,

A good feature given by microsoft in .Net 3.5 is adding new classes like TimezoneInfo, AdjustmentRule and TransitionTime.
Earlier we were able to get only the daylight changes of the timezone that is currently set on our machine using TimeZone.CurrentTimeZone and if we wanted other daylightchanges then we had to do lot of manipulation using Kernel.dll and access the registry values for each entry but now its readily available for us.

I had a requirement few days back to get the timezones and their next 5 years daylight start and end date and time, it just happened so easily with the given features.

The main thing that I had to implement is changing from transition time to DateTime and here is the function that I made to acheive the same.



public DateTime GetDateTime(int Year, TimeZoneInfo.TransitionTime transactionTime)
{
//Create a datetime to begin with 1st of the transition month           
DateTime dt = new DateTime(Year, transactionTime.Month,
1, transactionTime.TimeOfDay.Hour,
transactionTime.TimeOfDay.Minute, transactionTime.TimeOfDay.Second);

//If the dayofweek of 1st is same as the transition day then exit            
//otherwise             
if (dt.DayOfWeek != transactionTime.DayOfWeek)
{
//If transition dayofweek is greater than 1st dayofweek then we need to move further                
//Eg : Transition dayofweek is tuesday and 1st day of week is monday then we need to move 1 day ahead to point to                 
//the transition day                
if (dt.DayOfWeek < transactionTime.DayOfWeek)
{
dt.AddDays(transactionTime.DayOfWeek - dt.DayOfWeek);
}
else                
{
//else its not in the 1st week so we move 7 days ahead and move back again
                    dt = dt.AddDays(7 - (dt.DayOfWeek - transactionTime.DayOfWeek));
}
}

//Since we are already pointing to the first week of the transition date            
//Add remaining no of weeks to the datetime            
return dt.AddDays((transactionTime.Week - 1) * 7);
}


Sample source code 6Kb

By using the new classes we can get all the required information about the timezones accross the globe. Hope you found it useful.

Happy Learning,
Codingsense 🙂

Advertisements

6 Responses to “GetDaylightChanges with TimeZoneInfo”

  1. Ruben said

    Hi,

    Thank you for your post I found it very useful, however it doesn’t handle the case when TransitionTime.Week = 5 (Last week of the month). I replaced the last line with the following to handle that case:


    dt = dt.AddDays((transactionTime.Week - 1) * 7);

    //Handle transactionTime.Week = 5 (last week of the month)
    if (dt.Month != transactionTime.Month)
    {
    //The resulting date is from the next month, go back 1 week
    dt = dt.AddDays(-7);
    }

    return dt;

    • codingsense said

      Hi Ruben,

      Thanks for the suggestion. I will update the same in the post.

      Thanks,
      Codingsense

      • nicht verschlüsselt said

        Hi! Thank you for your method. It really saved me a lot of time. But the fix by Ruben is not attached at the method in the initial post. Please correct it to save even more time. 🙂

  2. Rich Alger said

    This was very helpful I added a method to it adapted from your code. I just wanted the dates daylight saving start and ends for a given TimeZone. I already tried:


    DaylightTime daylight = TimeZone.CurrentTimeZone.GetDaylightChanges(DateTime.Today.Year);

    But that only gives it for the time zone of the server. I needed to get a System.Globalization.DaylightTime for a timezone that observes Daylight Saving.


    ///
    /// Get the dates daylight saving starts and ends for a given timezone and year
    ///
    ///
    ///
    ///
    public static DaylightTime GetDaylightChanges(TimeZoneInfo InTimeZoneInfo, int InYear)
    {
    TimeZoneInfo.AdjustmentRule ruleFound = null;

    TimeZoneInfo.AdjustmentRule[] adjustments = InTimeZoneInfo.GetAdjustmentRules();
    if (adjustments.Length == 0)
    {
    throw new Exception(InTimeZoneInfo.StandardName + " has no adjustment rules");
    }
    //Find the correct adjustment rule
    foreach (TimeZoneInfo.AdjustmentRule adjustment in adjustments)
    {
    if (adjustment.DateStart.Year = InYear)
    ruleFound = adjustment;
    }
    if (ruleFound == null)
    {
    throw new Exception("No TimeZoneInfo.AdjustmentRule found for TimeZoneInfo "
    + InTimeZoneInfo.StandardName +" for year " + InYear);
    }

    DaylightTime outDaylightTime = new DaylightTime(
    GetDateTime(InYear, ruleFound.DaylightTransitionStart)
    , GetDateTime(InYear, ruleFound.DaylightTransitionEnd)
    , ruleFound.DaylightDelta);

    return outDaylightTime;
    }

    Here is the usage.


    TimeZoneInfo PacificTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
    DaylightTime daylight = CustomTimeZone.GetDaylightChanges(PacificTimeZone, 2010);
    Console.WriteLine("daylight.Start = " + daylight.Start);
    Console.WriteLine("daylight.End = " + daylight.End);
    Console.WriteLine("daylight.Delta = " + daylight.Delta);

  3. DaylightTime outDaylightTime = new DaylightTime(
    GetDateTime(InYear, ruleFound.DaylightTransitionStart)
    , GetDateTime(InYear, ruleFound.DaylightTransitionEnd)
    , ruleFound.DaylightDelta);
    in this above code GetDateTime is a default function if that so which language are you using. vb,net,c#,C++ ……
    I didnt found the method in vb.net.
    Please guide me through this.
    thanks in advance

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: