Reputation: 1735
I have some outdated code that attempts to account for the change in time caused by daylight savings that looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
for (int i = 1; i <= 31; i++)
{
DateTime dt = new DateTime(1960, 3, i, 0, 0, 0);
Console.WriteLine(dt.ToUniversalTime());
}
Console.WriteLine();
for (int i = 1; i <= 30; i++)
{
DateTime dt = new DateTime(1960, 4, i, 0, 0, 0);
Console.WriteLine(dt.ToUniversalTime());
}
Console.ReadKey();
}
}
}
This code iterates through the days in March and April in 1960 and prints the datetime. However, this does not correctly account for the time change in 1960, I believe because the date of the time change was different then. I attempted to fix this using the TimeZoneInfo class. I changed the code to the following:
class Program
{
static void Main(string[] args)
{
for (int i = 1; i <= 31; i++)
{
DateTime dt = new DateTime(1960, 3, i, 0, 0, 0);
var tz = TimeZoneInfo.Local;
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
//use timeZoneInfo class to account for dlst offset
Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset)));
}
Console.WriteLine();
for (int i = 1; i <= 30; i++)
{
DateTime dt = new DateTime(1960, 4, i, 0, 0, 0);
var tz = TimeZoneInfo.Local;
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
//use timeZoneInfo class to account for dlst offset
Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset)));
}
Console.ReadKey();
}
}
Unfortunately, this is printing out:
which shows that daylight savings is changing on April 3rd at 4 p.m., while it should be switching over at April 24th at 2:00 a.m. What am I missing to correctly account for daylight savings?
EDIT: My current time zone is eastern.
Upvotes: 3
Views: 1652
Reputation: 1500505
It looks like the Windows time zone information doesn't match what I'd have expected via TZDB. Here's a program using Noda Time to show all the transitions between ~1960 and 1965 with both the BCL TimeZoneInfo (wrapped) and the TZDB 2012i data:
using System;
using NodaTime;
class Test
{
static void Main()
{
var bcl = DateTimeZoneProviders.Bcl["Eastern Standard Time"];
var tzdb = DateTimeZoneProviders.Tzdb["America/New_York"];
ShowTransitions(bcl);
ShowTransitions(tzdb);
}
static void ShowTransitions(DateTimeZone zone)
{
Console.WriteLine("Transitions for {0}", zone.Id);
Instant start = Instant.FromUtc(1960, 1, 1, 0, 0);
Instant end = Instant.FromUtc(1965, 1, 1, 0, 0);
var interval = zone.GetZoneInterval(start);
while (interval.Start < end)
{
Console.WriteLine(interval.Start);
interval = zone.GetZoneInterval(interval.End);
}
Console.WriteLine();
}
}
Output:
Transitions for Eastern Standard Time
1959-10-25T06:00:00Z
1960-04-03T07:00:00Z
1960-10-30T06:00:00Z
1961-04-02T07:00:00Z
1961-10-29T06:00:00Z
1962-04-01T07:00:00Z
1962-10-28T06:00:00Z
1963-04-07T07:00:00Z
1963-10-27T06:00:00Z
1964-04-05T07:00:00Z
1964-10-25T06:00:00Z
Transitions for America/Toronto
1959-10-25T06:00:00Z
1960-04-24T07:00:00Z
1960-10-30T06:00:00Z
1961-04-30T07:00:00Z
1961-10-29T06:00:00Z
1962-04-29T07:00:00Z
1962-10-28T06:00:00Z
1963-04-28T07:00:00Z
1963-10-27T06:00:00Z
1964-04-26T07:00:00Z
1964-10-25T06:00:00Z
There are other time zone IDs which map to "Eastern Standard Time", but I haven't found any which match the Windows behaviour.
I don't think this is a TimeZoneInfo
bug - I believe it's a potential problem in the underlying Windows time zone data.
If you want to match TZDB data, of course, you can just use Noda Time :)
Upvotes: 2
Reputation: 45096
There is a dt.IsDaylightSavingTime(). And it changes on 4/4 for me (one day later than yours) in 1960 but I am CST. For 2012 it is correct on my system. It may be a bug. It may just be that year or all years up to X.
I think this explains it:
"In the early 1960s, observance of Daylight Saving Time was quite inconsistent, with a hodgepodge of time observances, and no agreement about when to change clocks."
"The Uniform Time Act of 1966 established a system of uniform (within each time zone) Daylight Saving Time throughout the U.S."
Upvotes: 1