您錯過了一個關鍵點:A DateTime
,其種類爲Local
並不總是完全代表一個獨特的時刻。這就是爲什麼沒有直接映射到Instant
。
在回退DST過渡期間,本地DateTime
可以表示兩個可能時刻中的任意一個。如果您打算將其轉換爲Instant
,那麼您需要在某個地方決定您應該選擇哪個時間段。
在你給出的答案,我假設你從下面的一個獲得timezone
:
var timezone = DateTimeZoneProviders.Tzdb.GetSystemDefault();
或
var timezone = DateTimeZoneProviders.Bcl.GetSystemDefault();
無論是確定此任務。然後代碼你給:
var localTime = LocalDateTime.FromDateTime(time);
var zonedTime = localTime.InZoneStrictly(timeZone);
return zonedTime.ToInstant();
這是完全正確的,但因爲你使用InZoneStrictly
,你將回退轉變過程中得到一個AmbiguousTimeException
。
您可以通過使用InZoneLeniently
來避免這種情況,它將選擇後兩種可能性(通常是「標準」時間)。但更重要的是,您可以改爲使用InZone
,並提供標準或自定義resolver以更精確地控制行爲。
關於你的原始的做法:
Instant.FromDateTimeUtc(time.ToUniversalTime())
這是確定,不會破壞你的數據,但明白這將依賴於當地的通用轉換BCL的行爲。它與InZoneLeniently
相同,因爲模糊值將被視爲「標準」時間。
這是NodaTime如何提供更精確的API的一個很好的例子。與其做出假設,您有機會具體並提供自定義行爲。最後你獲得了同樣的結果,但它將這個問題帶到了前臺而不是隱藏它。
感謝您花時間解釋這一點。我認爲這對其他對圖書館不熟悉的人會有幫助。 – Sam