2013-08-06 60 views
1

我有問題了解如何正確地將DateTime轉換爲不同的時區。可以說,我想將DateTime轉換爲時間:10:00(軍事)在美國東部時間到DateTime(UTC)。將DateTime從特定時區轉換爲UTC - 錯過了小時?

這裏是我的嘗試:

DateTime unspecified = new DateTime(2013, 8, 15, 10, 0, 0, DateTimeKind.Unspecified); 
var utc = TimeZoneInfo.ConvertTime(unspecified, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"), TimeZoneInfo.Utc); 

...我建構DateTimeDateTimeKind.Unspecified,因爲它既不UTC,也不當地時間(這是美國東部時間上午10點)。然後我將它傳遞給TimeZoneInfo.ConvertTime,告訴我這是EST中的DateTime,我想將其轉換爲UTC。

由於EST is 5 hours behind of Coordinated Universal Time (UTC)我期望utc等於{15.08.2013 15:00:00},然而當我運行上述餘碼,由於某種原因,得到{15.08.2013 14:00:00}(即時間差爲4小時)。

問題是:爲什麼?這是一種白天節省時間的問題嗎?如果是這樣 - 如何在沒有白天節省時間的情況下獲得此轉換?

+0

是的,夏令時是這個原因。不考慮它的簡單方法是簡單地使用'TimeZoneInfo'的'BaseUtcOffset':'新的DateTime(2013,8,15,10,0,0,DateTimeKind.Unspecified) .Subtract(TimeZoneInfo.FindSystemTimeZoneById (「東部標準時間」)。BaseUtcOffset);'但是,我不確定這是否會在某些特殊情況下出現,哪些可能會出現。 –

回答

0

是的,應用了dalylight保存。見Wikipedia

地方觀測標準 時間(秋/冬)時使用東部標準時間(EST)是5小時後面協調世界時 (UTC-05:00)。

東部夏令時間(EDT),觀察夏令時 (春/夏季)時爲4小時後面協調世界時 (UTC-04:00)。

轉換方法是正確的。你對EST時區的假設是有缺陷的。如果你的輸入日期真的是EST,那麼轉換是正確的。如果這不符合您的期望,您需要檢查輸入數據的來源以及輸入的時區。 如果您正在處理數據庫中保存的日期,並且您不知道什麼是正確的,哪些不是您遇到麻煩。

一般來說,使用DateTimeOffset代替DateTime更安全,因爲它始終將UTC時間存儲爲DateTime,並將本地時區偏移作爲附加值存儲在其中。這使得從本地時間確定真正的UTC時間變得微不足道。

1

具有Id"Eastern Standard Time"的Windows時區不僅適用於EST。它涵蓋了EST(-5)和EDT(-4)。你不會僅僅從id名稱中知道它。這是一個命名異常是Microsoft Windows時區數據庫的幾個棘手的事情之一。有關更多信息,請參見the timezone tag wiki

幸運的是,它並不是唯一的數據庫。它甚至不是最常用的數據庫,它只是Windows和.Net附帶的默認值。要做到這一點的轉換與標準IANA時區數據庫,使用Noda Time

DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"]; 
LocalDateTime dt = new LocalDateTime(2013, 8, 15, 10, 0, 0); 
ZonedDateTime zdt = tz.AtLeniently(dt); 
Instant utc = zdt.ToInstant(); 

還要注意野田佳彥時間如何讓你不能被誤解的類型。沒有影響行爲的Kind。 「本地」這裏只是意味着一些本地值,而不是你自己的本地時鐘。

另請注意,我使用AtLeniently將日期應用於時區。這是一種策略,在應用模糊或無效時間時進行調整。還有AtStrictly,這將在這些情況下引發異常。或者,您可以創建自己的策略。 TimeZoneInfo類沒有這個級別的控制。