Reputation: 962
DateTime dt = new DateTime(1972, 4, 24, 0, 0, 0);
Response.Write("dt: " + dt.ToString("M/d/yyyy h:mm:ss tt") + "<br />");
Response.Write("dt.Kind: " + dt.Kind.ToString() + "<br />");
Response.Write("dt.ToUniversalTime(): " + dt.ToUniversalTime().ToString("M/d/yyyy h:mm:ss tt") + "<br />");
displays
dt: 4/24/1972 12:00:00 AM
dt.Kind: Unspecified
dt.ToUniversalTime(): 4/24/1972 7:00:00 AM
which is incorrect. April 24, 1972 at 12 PM Pacific is actually April 24, 1972 at 8 AM UTC.
I have confirmed the correct UTC conversion with iOS's internal UTC date conversation and www.timeanddate.com and the UTC time should be 8 AM. Am I doing something wrong?
The server is running in "Pacific Time" timezone so ToUniversalTime should be converting from Pacific timezone to UTC since Unspecified is treated like Local.
Upvotes: 1
Views: 2272
Reputation: 126072
If you're on a machine that's not on Pacific Standard Time, you can see this behavior using the following code:
DateTime dt = new DateTime(1972, 4, 24, 0, 0, 0);
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
Console.WriteLine (TimeZoneInfo.ConvertTimeToUtc(dt, tz));
// 4/24/1972 7:00:00 AM
If you look at navy.mil's history of daylight saving time, you'll notice the following paragraph:
The Uniform Time Act of 1966 provided standardization in the dates of beginning and end of daylight time in the U.S. but allowed for local exemptions from its observance. The act provided that daylight time begin on the last Sunday in April and end on the last Sunday in October, with the changeover to occur at 2 a.m. local time.
And then a little later on:
In 1986, a law was passed that shifted the starting date of daylight time to the first Sunday in April, beginning in 1987
So the DST switchover wasn't the first Sunday in April until 1987, but for some reason .NET is acting as if it was.
Timeanddate.com's history of DST seems to agree, and lists April 30, 1972 (the last Sunday in April) as the date clocks were turned forward one hour (to UTC-7).
Microsoft's DST adjustment rules for times before 1987 appear to be wrong (and I'm not the only one who thinks so).
Here's what TimeZoneInfo
lists as the rules for PST:
Basically, Microsoft has ignored the historical rules and chosen to use rules put into effect in 1987 for dates that happened before those rules even existed.
Essentially your date (in 1972) is being handled incorrectly by Microsoft's TimeZoneInfo
adjustment rules.
If you're looking for a library that handles these types of time zone rules much better, check out NodaTime, which handles this particular case correctly:
var pacific = DateTimeZoneProviders.Tzdb["America/Los_Angeles"];
LocalDateTime localDateTime = new LocalDateTime(1972, 4, 24, 0, 0);
ZonedDateTime zonedDateTime = pacific.AtStrictly(localDateTime);
DateTime utcDateTime = zonedDateTime.ToDateTimeUtc();
Console.WriteLine(utcDateTime);
// 4/24/1972 8:00:00 AM
Upvotes: 6