野田時間でのシステムの LocalDateTime の取得
質問
システムの時間を取得する慣用的な方法は何ですか? LocalDateTime
野田時間で?私が考えることができる最も直接的な方法は次のとおりです
var dt = DateTime.Now
LocalDateTime systemTime = new LocalDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute);
しかし、野田時間のことを考えると、 全体の目的は、DateTime をより適切なセマンティクスを持つものに置き換えることです。, 、を使用するよりも好ましい方法があると思いました DateTime
上記の方法で。野田の施設を使って私が思いついた最善の方法は、
var zone = NodaTime.TimeZones.BclDateTimeZone.ForSystemDefault();
LocalDateTime systemTime = SystemClock.Instance.Now.InZone(zone).LocalDateTime;
しかし、これはかなり冗長に思えます。
解決
2 番目の例は、まさにこれを行う方法です。それは 意図的に 冗長。見る ノダタイムの設計思想.
それを 3 つの部分に分けて考えてみましょう。
現在の瞬間を取得します。
// Instant now = SystemClock.Instance.Now; // NodaTime 1.x Instant now = SystemClock.Instance.GetCurrentInstant(); // NodaTime 2.x
システムのタイムゾーンを取得します。(これが推奨される構文です)
DateTimeZone tz = DateTimeZoneProviders.Bcl.GetSystemDefault();
タイムゾーンをインスタントに適用します。
ZonedDateTime zdt = now.InZone(tz);
を取得するための最後のステップ LocalDateTime
これは簡単なことですが、これを行うと、タイムゾーン情報がすべて削除されることに注意してください。NodaTime の「ローカル」とは、 ない 「コードが実行されているコンピュータに対してローカル」を意味します。(つまり、そういうわけではない) DateTimeKind.Local
)
さらに考慮すべき点:
を使用して時計を抽象化することをお勧めします。
IClock
インターフェース:IClock clock = SystemClock.Instance; // Instant now = clock.Now; // NodaTime 1.x Instant now = clock.GetCurrentInstant(); // NodaTime 2.x
次に、クロックをメソッド パラメータとして渡すことも、お気に入りの DI/IoC フレームワークでクロックを挿入することもできます。(Autofac、Ninject、StructureMap、その他何でも...)。利点は、
NodaTime.Testing.FakeClock
単体テスト中に。見る Noda Time による単体テスト 詳細については。を渡すこともできます。
DateTimeZone
そのため、システムのタイムゾーンに縛られることなく、どこでもコードを実行できます。これはサーバー アプリケーションでは重要ですが、デスクトップ/モバイル アプリケーションではそれほど重要ではありません。IANA タイム ゾーンを使用する他の作業がある場合、または Noda Time の .NET Standard ビルドを使用している場合は、ステップ 2 を変更して、
Tzdb
プロバイダー:DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault();
TZDB ゾーンは、BCL ゾーンよりもはるかに正確です。Noda Time は、この最初の呼び出しでシステムの Windows (BCL) タイム ゾーンを IANA (TZDB) タイム ゾーンにマップします。
その理由に興味があるなら DateTime.Now
Noda Time は非常にコンパクトですが、Noda Time は非常に冗長なので、逆コンパイルしてみてください DateTime.Now
または MS の参照ソースを参照してください。内部では基本的に同じ手順を実行していることがわかります。