64

DateTime標準形式からUTCへの変換はどのように機能しますか?

具体的には、DateTimeあるタイムゾーンでオブジェクトを作成し、別のタイムゾーンに切り替えて実行ToUniversalTime()した場合、変換が正しく行われ、時間が正確に表現されていることをどのようにして知ることができますか?

4

4 に答える 4

75

DateTimeオブジェクトにアタッチされた暗黙のタイムゾーンはありません。その上で実行ToUniversalTime()すると、コードが実行されているコンテキストのタイムゾーンが使用されます。

たとえば、DateTime1970年1月1日のエポックからを作成するDateTimeと、世界のどこにいても同じオブジェクトが得られます。

グリニッジでコードを実行ToUniversalTime()しているときに実行すると、同じ時間が発生します。バンクーバーに住んでいるときにそれを行うとDateTime、-8時間のオフセットオブジェクトが得られます。

これが、あらゆる種類の日付変換またはローカリゼーションを行う必要がある場合に、時間関連情報をUTC時間としてデータベースに保存することが重要である理由です。コードベースが別のタイムゾーンでサーバー機能に移動したかどうかを検討してください;)

編集:ジョエルの答えからのメモ-DateTimeデフォルトでは、オブジェクトはとして入力されDateTimeKind.Localます。日付を解析してとして設定するとDateTimeKind.UtcToUniversalTime()変換は実行されません。

そして、これが「日時を使用したコーディングのベストプラクティス」に関する記事と、.Netを使用した日時の変換に関する記事です。

于 2009-07-29T16:13:22.307 に答える
35

まず、がすでに UTC であることがわかっているKindかどうかを確認します。DateTimeその場合は、同じ値を返します。

それ以外の場合は、ローカル時間であると想定されます。これは、それが実行されているコンピューターに対してローカルであり、特に、プライベート プロパティが最初に遅延初期化されたときにコンピューターが使用していたタイム ゾーンです。つまり、アプリケーションの起動にタイム ゾーンを変更すると、古いタイム ゾーンが引き続き使用される可能性が高くなります。

タイム ゾーンには、現地時間を UTC 時間に、またはその逆に変換するのに十分な情報が含まれていますが、あいまいまたは無効な時間もあります。(2 回発生する現地時間と、夏時間のためにまったく発生しない現地時間があります。) これらのケースを処理するための規則は、ドキュメントで指定されています。

日付と時刻のインスタンス値があいまいな時刻の場合、このメソッドはそれが標準時刻であると想定します。(あいまいな時間とは、ローカル タイム ゾーンの標準時間または夏時間にマップできる時間です) 日付と時刻のインスタンス値が無効な時間である場合、このメソッドはローカル タイム ゾーンの時刻からローカル時間を単純に減算します。 UTC を返すための UTC オフセット。(無効時間とは、夏時間調整規則の適用により存在しない時間です。)

返される値にはKindofDateTimeKind.Utcがあるため、それを呼び出すとToUniveralTime、オフセットが再度適用されることはありません。(これは .NET 1.1 からの大幅な改善です!)

非ローカル タイム ゾーンが必要な場合TimeZoneInfoは、.NET 3.5 で導入されたものを使用する必要があります (以前のバージョンにはハッキーなソリューションがありますが、適切ではありません)。瞬間を表すにはDateTimeOffset、.NET 2.0SP1、.NET3.0SP1、および .NET 3.5 で導入された which の使用を検討する必要があります。ただし、これにはまだ実際のタイム ゾーンが関連付けられていません。UTC からのオフセットだけです。つまり、たとえば、1 時間後の現地時間がわからないことを意味します。DST ルールは、その特定の瞬間に同じオフセットを使用するタイム ゾーン間で異なる場合があります。やや単純化されているのとはTimeZoneInfo対照的に、歴史的および将来のルールを考慮に入れるように設計されています。TimeZone

基本的に、.NET 3.5 でのサポートは以前よりも大幅に改善されていますが、適切なカレンダー計算にはまだ何かが必要です。Joda Timeを .NET に移植したい人はいますか? ;)

于 2009-07-29T16:21:47.797 に答える
7

@wompの発言に加えて、DateTime の Kind プロパティをチェックして、既にUTC 日付であるかどうかを確認します。

于 2009-07-29T16:16:35.547 に答える
4

DateTime.ToUniversalTime は、ローカル タイムゾーンのタイムゾーン オフセットを削除して、DateTime を UTC に正規化します。次に、別のタイムゾーンの正規化された値で DateTime.ToLocalTime を使用すると、そのタイムゾーンで正しく表現するために、そのタイムゾーンのタイムゾーン オフセットが正規化された値に追加されます。

于 2009-07-29T16:19:31.797 に答える