2017-02-23 88 views
4

我在時區被視爲字符串的應用程序,通過使用該系統的名稱,所以我們可以通過做使實際System.TimeZoneInfo對象:獲取亞利桑那標準時間在.NET

var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZone); 

這些價值是堅持到DB,現在我們正面臨一個問題,其中一個這樣的對象被要求在Arizona Time這不是一個標準的時區。從我調查的Arizona Time更改時區,因爲它沒有遵守「日光節約」的事實。

我正在尋找一種方法來設置數據庫中的一個值,以便不需要根據日光節省更改來更改它。

有沒有辦法做到這一點?

即使我必須更改一點代碼才能獲得TimeZoneInfo對象。真正重要的對我來說是一種方法來確定對應Arizona Time

回答

4

關於亞利桑那時區

timeanddate.com

有一種普遍的誤解,認爲亞利桑那州的夏季和山地標準時間(MST) 期間在太平洋夏令 時間(PDT)冬天。由於MST和PDT具有相同的UTC偏移量 減7小時(UTC-7),因此亞利桑那州與當地的時間相同 在夏季表示加州和內華達州。 雖然 時間是相同的,亞利桑那州使用標準時間(MST)全年。 「日光」時區,如MDT,主要用於地區是 開關DST每年

IANA(TZ數據庫)時區數據庫包含亞利桑那州兩個地時區:

  • 美國/鳳凰(山地標準時間 - 亞利桑那,納瓦霍除外),這確實不觀察夏令時(DST),並
  • 美國/希普羅克,它觀察DST。

亞利桑那時區在.NET

根據您的用戶在亞利桑那州的確切位置,你應該使用美國/鳳凰美國/希普羅克時區,所以你將需要兩個值在數據庫中。但是,如果您嘗試使用TZ數據庫名,以獲取時區與TimeZoneInfo.FindSystemTimeZoneById,你會得到System.TimeZoneNotFoundException

爲了得到不遵守DST(美國/鳳凰)亞利桑那州的時區,你可以使用:

TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time") 

爲了獲得亞利桑那時區,做遵守DST(美國/希普羅克),你可以使用:

TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time") 

所以,你將有兩個IDS在數據庫中,US Mountain Standard TimeMountain Standard Time,或者一些其他字符串ŧ您稍後將映射到這些.NET時區ID。

退房NodaTime,它可以幫助你很多,當談到處理日期,時間和時區。

最後,這裏是一個演示.NET 美國山地標準時間美國/鳳凰,亞利桑那州沒有DST)和山地標準時間美國/之間的差異的樣本程序(帶NodaTime) Shiprock,亞利桑那州與DST)。

using System; 

using NodaTime; 
using NodaTime.TimeZones; 

namespace TimeZoneExample 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Arizona without daylight saving time (TZ: America/Phoenix) 
      var mstWithoutDstTz = TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time"); 

      // Arizona with daylight saving time (TZ: America/Shiprock) 
      var mstWithDstTz = TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time"); 

      // NodaTime BclDateTimeZone for Arizona without daylight saving time 
      var mstWithoutDstNodaTz = BclDateTimeZone.FromTimeZoneInfo(mstWithoutDstTz); 

      // NodaTime BclDateTimeZone for Arizona with daylight saving time 
      var mstWithDstNodaTz = BclDateTimeZone.FromTimeZoneInfo(mstWithDstTz); 

      // January 1, 2017, 15:00, local winter date 
      var localWinterDate = new LocalDateTime(2017, 01, 01, 15, 00); 

      // NodaTime ZonedDateTime for Arizona without daylight saving time: January 1, 2017, 15:00 
      var winterTimeWithoutDst = mstWithoutDstNodaTz.AtStrictly(localWinterDate); 

      // NodaTime ZonedDateTime for Arizona with daylight saving time: January 1, 2017, 15:00 
      var winterTimeWithDst = mstWithDstNodaTz.AtStrictly(localWinterDate); 

      // Both time zones have the same time during winter 
      Console.WriteLine($"Winter w/o DST: {winterTimeWithoutDst}"); // 2017-01-01T15:00:00 US Mountain Standard Time (-07) 
      Console.WriteLine($"Winter w/ DST: {winterTimeWithDst}"); // 2017-01-01T15:00:00 Mountain Standard Time (-07) 

      // add 180 days to get June 30, 2017 
      var sixMonthsToSummer = Duration.FromTimeSpan(new TimeSpan(180, 0, 0, 0)); 

      // During summer, e.g. on June 30, Arizona without daylight saving time is 1 hour behind. 
      Console.WriteLine($"Summer w/o DST: {winterTimeWithoutDst + sixMonthsToSummer}"); // 2017-06-30T15:00:00 US Mountain Standard Time (-07) 
      Console.WriteLine($"Summer w/ DST: {winterTimeWithDst + sixMonthsToSummer}"); // 2017-06-30T16:00:00 Mountain Standard Time (-06) 
     } 
    } 
} 
2

如果我理解你的問題正確,你想創建一個表示「亞利桑那時間」,它具有恆定的UTC的偏移量,無論日期自定義時區的實際時區的一年。

如果是這樣,你應該能夠使用靜態方法

TimeZoneInfo.CreateCustomTimeZone 

剛剛成立時間跨度來的時間從UTC,你需要它(-7從我可以告訴小時)的數量。

https://msdn.microsoft.com/en-us/library/bb309898(v=vs.110).aspx

編輯:您還可以通過簡單地使用命名的時區

"US Mountain Standard Time" 

這應該代表了相同的一些成功。

相關問題