2012-11-08 27 views
3

我試圖解釋引起日光節約時間的變化,看起來像這樣一些過時的代碼時間的變化:使用的TimeZoneInfo類佔夏令時

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(); 
     } 
    } 
} 

通過此代碼迭代1960年3月和4月的日期並打印日期時間。 但是,這並沒有正確解釋1960年的時間變化,我相信因爲時間變化的日期不同。我試圖用TimeZoneInfo類來解決這個問題。我改變了代碼如下:

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(); 
     } 
    } 

不幸的是,這是打印出來: enter image description here

這表明夏令時下午4點4月3日發生變化,而應該在四月切換24日凌晨2點,我錯過了什麼來正確解釋夏令時?

編輯: 我目前的時區是東部。

+3

這是非常* *很難回答這個不知道你在說什麼時區。另外請記住,Windows的時區概念並不總是與TZDB相同。 –

+0

我的時區是東部的,但會影響到1960年應用夏令時的日期嗎? – Christian

+1

@Christian,對,時區的DST規則不同。甚至有時區是規則是沒有規則只是一個任意選擇的日期。 –

回答

2

它看起來像Windows時區信息不符合我所期望通過TZDB。下面是使用Noda Time顯示所有〜1960年和1965年之間的過渡方案既BCL的TimeZoneInfo(包裹)和TZDB 2012i數據:

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(); 
    } 
} 

輸出:

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 

還有其他時區ID映射到「東部標準時間」,但我還沒有找到任何匹配Windows行爲的ID。

我不認爲這是一個TimeZoneInfo錯誤 - 我認爲這是潛在的Windows時區數據問題。

如果你想匹配TZDB數據,當然,你可以用野田佳彥時間:)

+0

DateTimeZoneProviders.Tzdb [「美國/紐約」]對我來說不存在(拋出異常;實際上在你的輸出中有「美國/多倫多」),但是有沒有一個列表將城市映射到適當的時區? –

+0

實際上帶有下劃線的「America/New_York」存在...,但仍然有一個列表在某處?喜歡把地圖說成「拉斯維加斯」到任何時區... –

+0

@PaulWestcott:修正,謝謝 - 對於錯字感到抱歉。我害怕,我不知道有一張好的地圖列表。 –

1

有一個dt.IsDaylightSavingTime()。 1960年,我在4/4(比你的晚一天)變化,但我是CST。對於2012年,我的系統是正確的。這可能是一個錯誤。這可能只是當年或歷年最多十

我認爲這解釋了它:

Daylight Saving Time

「在60年代初,夏令時的遵守是頗不一致,有一個大雜燴的時間紀念,並沒有就何時改變時鐘達成一致。「

「1966年的統一時間法案在全美的夏令時制定了統一制度(在每個時區內)」。