リトルミラクルズC#/。NET-DateTimeOffset構造

ささいに見えますが、記述と保守の両方でコードを簡単にすることができる.Net Frameworkの一部を考えてみましょう。





.NETで記述している(そして、もしそれを行わないのなら、この投稿を無駄に読んでいる)人は、必要に応じてDateTime構造体を時々使用するでしょう。 この構造は、ローカルタイムゾーン(またはUTC)に関連する日付、時刻、または日付/時刻を保存するのに便利です。





ただし、時間をオフセットとして保存し、現地時間に変換しない場合があります。 そして、ここで、.NET 3.5で最初に登場した構造-DateTimeOffset-が役立ちます。



問題:日時の解析により現地時間に変換される可能性がある



ファイル、Webサービスなどを使用していると想像してください。 サーバーが異なるタイムゾーンにあるサードパーティ企業。 さらに、返されるデータにはいくつかのフィールドがあり、日付を含める必要がありますが、実際には深夜に設定されるDateTime構造のシリアル化されたインスタンスが含まれます。 たとえば、次の形式で患者の生年月日を提供します。



2012-03-01 00:00:00-05-05



そのような記録は、その人が2012年3月1日に不特定の時間に生まれたことを示しています(最終的に、ほとんどのフォームでは、出生時間を記入する必要はありません)。 ただし、DateTime構造体のインスタンスは「ヘッドオン」でシリアル化されているため、タイムゾーンに従って深夜に設定された時刻が含まれています。





そのため、この日付は東部標準時と互換性があり、中央標準時であることがわかっているため、次のように解析します。



// // ..

var dateString = "2012-03-01 00:00:00-05:00";

// DateTime

var birthDay = DateTime.Parse(dateString);







完璧に見えますよね? しかし、ここに問題があります。 セントラルタイムゾーンが設定されているローカルマシンでDateTimeオブジェクトの内容を確認すると、次のように表示されます。



2012-02-29 11:00:00 PM



どうした (または、あるキャラクターが言ったように-誰がこれをしたのですか?) 彼らはあなたにサービスを提供しました-彼らは指定された日付と時刻をあなたのローカルの日付と時刻に変換しました。 3月1日から2月29日まで移動した誕生日に関するものでなければ、これはそれほど悪くありません。





もちろん、サードパーティに電話して、日付の文字列に時間を含めることを停止するか、時間とともにオフセットの送信を停止するように要求することができます(この場合、ローカル時間に変換されませんが、DateTimeKind.Unspecifiedとしてマークされます)。





ただし、この方法で変化を起こす機会はありません。





オフセット付きの日付と時刻を読み取りたいが、ローカルタイムゾーンに変換したくない場合があります。 ここで、DateTimeOffsetが役立ちます。



DateTimeOffset-DateTimeとOffsetを保存します



では、DateTimeOffsetはどうでしょうか? 構造はその名前と同じくらい簡単で、DateTimeOffsetは日付+時間+オフセットです。 これは、現在の日付と時刻が設定されたオフセットに関する情報が含まれているため、はるかに正確な時点を表す理由です。





実際、DateTimeとDateTimeOffsetの機能は多くの点で重複しています。Microsoftにはどちらかを選択するためのガイドがあるので、MSDNでそれをよく理解することをお勧めします。 この記事のタイトルは「DateTime、DateTimeOffset、およびTimeZoneInfoの選択」です。





一般に、同じタイムゾーンに「接続」されている場合、またはUTCの世界時のみを使用する場合は、DateTimeを使用できます。 ただし、異なるタイムゾーンの日付と時刻を使用し、ローカル時刻に変換せずにオフセット情報を保存する場合は、DateTimeOffsetを使用することをお勧めします。





DateTimeOffset構造には、DateTime構造と同じ多くのプロパティ(日、月、年、時間、分、秒など)があるため、ここでは説明しません。 主な違いは、いくつかの新しい機能です。



日時



オフセットなしのDateTimeを返します。



現地時間



オフセット(ローカルタイムゾーン)を考慮して、変換されたDateTimeを返します。



オフセット



UTCからのオフセットを返します。



UTCDATETIME



DateTimeをUTC時間として返します。





DateTimeプロパティはDateTime(ローカルタイムゾーンにキャストされない)を返し、OffsetプロパティはUTCからのオフセットを表すTimeSpan形式を持ちます。 また、ローカルタイムゾーンまたはUTCの指定されたDateTimeOffsetをDateTimeに変換するLocalDateTimeおよびUtcDateTimeプロパティがあります。





また、DateTimeOffset構造体のNowプロパティとUtcNowプロパティはDateTime型を返さず、UTCからの対応するオフセットを持つDateTimeOffsetsを返します。 もちろん、DateTimeと同様に、DateTimeOffsetには日付/時刻を処理するメソッドがあり、DateTimeではなくDateTimeOffset型を返します。





それでは、上記の例では、これらすべてがどのように役立つのでしょうか? これで、サードパーティからタイムゾーンの日付と時刻が送信され、ローカルの日付/時刻に変換する必要がないことがわかりました。 したがって、DateTimeOffset.Parse()(またはTryParse())を使用して、日付のみを選択できます。



// // ..

var dateString = "2012-03-01 00:00:00-05:00";

// / ( /)

var dtOffset = DateTimeOffset.Parse(dateString);

// DateTime

// Date

//

var theDay = dtOffset.Date;








したがって、「真夜中シフト」を追跡することなく日付を簡単に解析したり、現地時間に変換せずに日付、時刻、オフセットが必要な場所で使用したりできます。



まとめ



DateTime構造は、日付/時刻の解析、操作、および比較の点では非常に強力ですが、さまざまなタイムゾーンの形式で日付を操作するのに多くの不愉快な分を提供できます。 この場合のDateTimeOffsetは、UTCからのオフセットを使用するため、はるかに柔軟です。





無料の翻訳(c)V.F. Alien別名hDrummer、 オリジナルはこちら



All Articles