-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
On Unix, time zone data is retrieved from tzfiles. See https://linux.die.net/man/5/tzfile.
The transition times of each time zone are stored in this file. Every time the offset from UTC changes, an entry is made. In practice, they are "forecasted" out until about 2037.
In V2 of the tzfile, the time transitions after this "last" transition date are represented by a "POSIX" style string that represents when DST starts and ends each year.
These POSIX-TZ-environment-variable-style strings are documented http://man7.org/linux/man-pages/man3/tzset.3.html.
Here is an example for New Zealand, where the standard time (NZST) is
12 hours ahead of UTC, and daylight saving time (NZDT), 13 hours
ahead of UTC, runs from the first Sunday in October to the third
Sunday in March, and the changeovers happen at the default time of
02:00:00:
TZ="NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0"
However, our GetAdjustmentRules() method is not translating this information correctly.
Here is an example of using the America/Los_Angeles time zone and printing out the AdjustmentRules. Notice the top row says to start daylight transitions on the November 1 of each year, and to end it on December 31. Also notice that there is no DaylightDelta during this time, when it should be 1 hour.
DateStart DateEnd DaylightDelta DaylightTransitionStart DaylightTransitionEnd
11/01/2037 12/31/9999 00:00:00 M11.w1.d1 1:00 AM M12.w1.d31 11:59 PM
03/08/2037 11/01/2037 01:00:00 M3.w1.d8 3:00 AM M11.w1.d1 1:59 AM
11/02/2036 03/08/2037 00:00:00 M11.w1.d2 1:00 AM M3.w1.d8 1:59 AM
03/09/2036 11/02/2036 01:00:00 M3.w1.d9 3:00 AM M11.w1.d2 1:59 AM
11/04/2035 03/09/2036 00:00:00 M11.w1.d4 1:00 AM M3.w1.d9 1:59 AM
Code to print the above table
class Program
{
static void Main(string[] args)
{
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
StringBuilder builder = new StringBuilder();
builder.Append("DateStart");
builder.Append("\t");
builder.Append("DateEnd");
builder.Append("\t");
builder.Append("\t");
builder.Append("DaylightDelta");
builder.Append("\t");
builder.Append("DaylightTransitionStart");
builder.Append("\t");
builder.Append("DaylightTransitionEnd");
System.Console.WriteLine(builder);
var rules = tz.GetAdjustmentRules();
foreach (var rule in rules.Reverse().Take(5))
{
builder = new StringBuilder();
builder.Append(rule.DateStart.ToString("MM/dd/yyyy"));
builder.Append("\t");
builder.Append(rule.DateEnd.ToString("MM/dd/yyyy"));
builder.Append("\t");
builder.Append(rule.DaylightDelta);
builder.Append("\t");
PrintTransition(rule.DaylightTransitionStart, builder);
builder.Append("\t");
PrintTransition(rule.DaylightTransitionEnd, builder);
System.Console.WriteLine(builder);
}
}
private static void PrintTransition(TimeZoneInfo.TransitionTime transition, StringBuilder builder)
{
builder.Append($"M{transition.Month}.w{transition.Week}.d{transition.Day} {transition.TimeOfDay.ToShortTimeString()}");
}
}