2013-10-17 22 views
9

DateTimeInstantに変換したい場合があります。私はDateTimeKindLocalになると信じています。ローカルのDateTimeをInstantに変換する方法を教えてください。

Instant.FromDateTimeUtc(time.ToUniversalTime()) 

「これは合理的なようだが、私はこれは完全に信頼できるとのdoesnであることを特定したい:DateTime私は図書館で見つけることができる最も近いです、timeという変数であることを考えると

データの損失または破損のリスクがあります。私はこれが変換を行う最善の方法であるかどうか、そうするより信頼できる手段があるかどうかはわかりません。

私はNodaTimeのBCL Conversionsページを見て、そしてそれは、このシナリオについては、以下の言った:

注全く変換がLocalの一種でDateTimeに存在しないこと - これが効果的にシステムのデフォルトの時間のためになりますゾーンは、一般的にはじめて明示する必要があります。

答えて

16

重要な点が1つもありません:の種類がLocalである場合は、必ずしも固有の瞬間を完全に表すとは限りません。そのため、Instantへの直接マッピングはありません。

フォールバックのDSTトランジションでは、ローカルDateTimeは2つの可能な瞬間のいずれかを表すことができます。 Instantに変換する場合は、選択する必要がある瞬間を決める必要があります。あなたが与えた答えで

、私はあなたが以下のいずれかからtimezoneを得たと仮定しています:

var timezone = DateTimeZoneProviders.Tzdb.GetSystemDefault(); 

または

var timezone = DateTimeZoneProviders.Bcl.GetSystemDefault(); 

のどちらかが、このタスクのためにOKです。そして、あなたが与えたコード:

var localTime = LocalDateTime.FromDateTime(time); 
var zonedTime = localTime.InZoneStrictly(timeZone); 
return zonedTime.ToInstant(); 

これはまさに正しいですが、InZoneStrictlyを使用するので、あなたは、フォールバック遷移中AmbiguousTimeExceptionを取得します。

次の2つの可能性(通常は「標準」時間)の後者を選ぶであろう、InZoneLenientlyを使用することによって、これを回避することができます。しかし、もっと重要なのは、あなたの代わりにInZoneを使用して、より正確に動作を制御するために、標準またはカスタムresolverのいずれかを提供することができます。

の元のアプローチについて:

Instant.FromDateTimeUtc(time.ToUniversalTime()) 

これはokですし、データ破損していないだろうが、それは普遍的変換に地元のBCLの動作に依存することを理解しています。あいまいな値が「標準」時間として扱われる点でInZoneLenientlyと同じです。

NodaTimeがより正確なAPIを提供する方法の素晴らしい例です。前提を作るのではなく、具体的な行動をとる機会があります。最終的に同じ結果が得られましたが、それを隠すのではなく、前景にこの問題をもたらしました。

+0

これを説明する時間をとってくれてありがとう。私はこれが、図書館を初めて知り尽くした他の人々に役立つと思います。 – Sam

1

私はちょうど私がNodaTimeLocalDateTimeにローカル時間に変換してからToInstant続いInZoneのいずれかの方法を使用して瞬時にそれをマップすることができることに気づきました。

var localTime = LocalDateTime.FromDateTime(time); 
var zonedTime = localTime.InZoneStrictly(timeZone); 
return zonedTime.ToInstant(); 

これはtimeが実際にLocalであると仮定していることに留意してください:ここでは、時間のタイムゾーンがtimeZoneで提供されると仮定すると、時間が無効である場合は、エラーがスローされるようにしたいの例です。そうでない場合、結果は間違っていると私は信じています。

関連する問題