.NET TimeZone.CurrentTimeZone.GetDaylightChanges returns invalid DST for 2005
I have used the following code to display daylight saving time for years between 2005 and 2035.
During 2005, this page shows that DST is between April 3rd and October 30th. But GetDaylightChanges returns March 13 and Nov 6.
Is .NET GetDaylightChanges a reliable function?
public static void GetCurrentTimeZone()
{
for (int i = 0; i < 30; i++)
{
var dlt = TimeZone.CurrentTimeZone.GetDaylightChanges(2005 + i);
Console.WriteLine(2005 + i);
Console.WriteLine(dlt.Start.ToLongDateString());
Console.WriteLine(dlt.End.ToLongDateString());
Console.WriteLine(" ");
}
}
source to share
From 1987 to 2006, the rule was: DST runs from the first Sunday in April to the last Sunday in October.
From 2007 to the present, the rule was: DST is effective from the second Sunday in March to the first Sunday in November.
However, as @MaheshKava pointed out, the GetDaylightChanges API remarks section says this:
Because the TimeZone class supports only one daylight saving time rule, the GetDaylightChanges method applies the current adjustment rule in any year, regardless of whether the adjustment rule actually applies to that year.
This means that the current rule (2nd Sunday in March to 1st Sunday in November) applies for all years, regardless of whether or not the rule is in effect during that year. So, to sum it up, GetDaylightChanges will give you inaccurate results for any year prior to 2007, and apparently that's by design.
The API documentation further states that you can use TimeZoneInfo.GetAdjustmentRules to get more accurate information. I was curious about this, so I wrote this code:
static void Main(string[] args)
{
PrintAllDaylightSavingsAdjustmentDates();
Console.ReadLine();
}
public static void PrintAllDaylightSavingsAdjustmentDates()
{
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
TimeZoneInfo.AdjustmentRule[] adjustmentRules = timeZoneInfo.GetAdjustmentRules();
for (int year = 2000; year < 2030; year++)
{
PrintDaylightSavingsAdjustmentDatesForYear(adjustmentRules, year);
}
}
public static void PrintDaylightSavingsAdjustmentDatesForYear
(
TimeZoneInfo.AdjustmentRule[] adjustmentRules,
int year
)
{
DateTime firstOfYear = new DateTime(year, 1, 1);
foreach (TimeZoneInfo.AdjustmentRule adjustmentRule in adjustmentRules)
{
if ((adjustmentRule.DateStart <= firstOfYear) && (firstOfYear <= adjustmentRule.DateEnd))
{
Console.WriteLine("In {0}, DST started on {1} and ended on {2}.",
year,
GetTransitionDate(adjustmentRule.DaylightTransitionStart, year).ToString("MMMM dd"),
GetTransitionDate(adjustmentRule.DaylightTransitionEnd, year).ToString("MMMM dd"));
}
}
}
public static DateTime GetTransitionDate
(
TimeZoneInfo.TransitionTime transitionTime,
int year
)
{
if (transitionTime.IsFixedDateRule)
{
return new DateTime(year, transitionTime.Month, transitionTime.Day);
}
else
{
if (transitionTime.Week == 5)
{
// Special value meaning the last DayOfWeek (e.g., Sunday) in the month.
DateTime transitionDate = new DateTime(year, transitionTime.Month, 1);
transitionDate = transitionDate.AddMonths(1);
transitionDate = transitionDate.AddDays(-1);
while (transitionDate.DayOfWeek != transitionTime.DayOfWeek)
{
transitionDate = transitionDate.AddDays(-1);
}
return transitionDate;
}
else
{
DateTime transitionDate = new DateTime(year, transitionTime.Month, 1);
transitionDate = transitionDate.AddDays(-1);
for (int howManyWeeks = 0; howManyWeeks < transitionTime.Week; howManyWeeks++)
{
transitionDate = transitionDate.AddDays(1);
while (transitionDate.DayOfWeek != transitionTime.DayOfWeek)
{
transitionDate = transitionDate.AddDays(1);
}
}
return transitionDate;
}
}
}
Which spits out the following output:
In 2000, DST started on April 02 and ended on October 29.
In 2001, DST started on April 01 and ended on October 28.
In 2002, DST started on April 07 and ended on October 27.
In 2003, DST started on April 06 and ended on October 26.
In 2004, DST started on April 04 and ended on October 31.
In 2005, DST started on April 03 and ended on October 30.
In 2006, DST started on April 02 and ended on October 29.
In 2007, DST started on March 11 and ended on November 04.
In 2008, DST started on March 09 and ended on November 02.
In 2009, DST started on March 08 and ended on November 01.
In 2010, DST started on March 14 and ended on November 07.
In 2011, DST started on March 13 and ended on November 06.
In 2012, DST started on March 11 and ended on November 04.
In 2013, DST started on March 10 and ended on November 03.
In 2014, DST started on March 09 and ended on November 02.
In 2015, DST started on March 08 and ended on November 01.
In 2016, DST started on March 13 and ended on November 06.
In 2017, DST started on March 12 and ended on November 05.
In 2018, DST started on March 11 and ended on November 04.
In 2019, DST started on March 10 and ended on November 03.
In 2020, DST started on March 08 and ended on November 01.
In 2021, DST started on March 14 and ended on November 07.
In 2022, DST started on March 13 and ended on November 06.
In 2023, DST started on March 12 and ended on November 05.
In 2024, DST started on March 10 and ended on November 03.
In 2025, DST started on March 09 and ended on November 02.
In 2026, DST started on March 08 and ended on November 01.
In 2027, DST started on March 14 and ended on November 07.
In 2028, DST started on March 12 and ended on November 05.
In 2029, DST started on March 11 and ended on November 04.
source to share