DateTime.NowとDateTime.UtcNow


225

2つのプロパティがどのように機能するのかという原則は何なのでしょうか。2つ目は普遍的であり、基本的にタイムゾーンを処理しないことを知っていますが、誰かがそれらがどのように機能し、どのシナリオでどのシナリオを使用する必要があるかを詳細に説明できますか?


1
遅すぎることが、私はこのブログにポイントが必要になる場合がありますblog.angeloflogic.com/2013/10/...
カイ王

小さなベンチマーキングrextester.com/QRDR82396
Daniel B

回答:


346

DateTime.UtcNowは、グリニッジ標準時タイムゾーンとも呼ばれる協定世界時での日付と時刻を示します。基本的には、イギリスのロンドンにいるときのように、夏の間はそうではありません。DateTime.Nowは、現在のロケールで表示される日付と時刻を示します。

DateTime.Now人間に日付を表​​示しているときはいつでも使用することをお勧めします。つまり、彼らが見る値に快適であるようにすることです。それは、時計や時計に表示されるものと簡単に比較できるものです。DateTime.UtcNow日付を保存する場合、またはその方法で(クライアント/サーバーモデルで)後で計算に使用する場合に使用します。計算は、サーバーまたは異なるタイムゾーンのクライアントによって混乱することはありません。


84
優れた点- データベースまたはファイルに日付を保存するときは、必ずUTCで保存してください。
Jeff Atwood、

15
日付をデータベースのUTCに保存する場合は、明示的なタイムゾーンを指定しない日付にデータベースが独自のタイムゾーンを追加しないようにする必要があることに注意する必要があります。DateTimeは、要求されたときに常に現在のタイムゾーンを使用することに注意してください。
Omer van Kloeten 2008

@OmervanKloetenは非常に良い点を与えます。IISとSQLサーバーが異なるタイムゾーンにある場合でも、日付を正しく保存および受信するためのエレガントな「オールラウンド」ソリューションがあるかどうか疑問に思っています。
TheGeekZn 2014年

1
@ JoshYates1980はい、単にDateTime.UtcNow.AddYears(1)を実行します
CathalMF

3
使用NodaTime -それはあなたがより有用な方法で時間を考える強制的にこのような問題を避けるだろう
aateeque

86

とてもシンプルなので、聴衆が何で、どこに住んでいるかにもよると思います。

Utcを使用しない場合は、日付と時刻を表示する相手のタイムゾーンを知っている必要があります。そうでない場合は、システム時間またはサーバー時間の午後3時に発生した何かが実際に午後5時に発生したことを伝えます。彼らはたまたま生きている。

私たちが使用しDateTime.UtcNowているのは、世界中にウェブユーザーがいることと、すべてのユーザーが自分の住んでいるタイムゾーンを示すフォームに記入するのを嫌がらないようにするためです。

また、投稿が古くなり、地球上のどこにいても時刻が「同じ」になるまでの相対時間(2時間前、1日前など)も表示されます。


また、DateTime.UtcNowを格納する必要があるのは、正しい時間を取得するために2つの日付を使用した計算が行われる場合のみです。RegisterAt Dateを表示する必要がある場合は、Datetime.Nowで十分です。
Elisabeth

36

パフォーマンスの違いにも注意してください。内部は多くのタイムゾーン調整を行っているため、DateTime.UtcNow30倍高速です(これはReflectorで簡単に確認できます)。DateTime.NowDateTime.Now

したがってDateTime.Now、相対時間測定には使用しないでください。


それはちょうどUtcNowがより良い性能を持っており、単にMySQLであなたの日付を保存し、それがUTCであると仮定し、UtcNowと日付依存のディスプレイを比較すると、このグローバルタイムゾーンの問題を簡素化することを知っている私に痛みを伴う旅してきました
Diin

29

.NETで理解するための一つのメインコンセプトは、ということである今がある今、すべての地球上であなたが何であるかを時間帯に関係なく、だからと変数ロードした場合。DateTime.NowまたはDateTime.UtcNow-割り当ては同じです*あなた。DateTimeオブジェクトは、あなたがしているタイムゾーンを知っています割り当てに関係なくそれを考慮に入れます。

の有用性DateTime.UtcNowは、夏時間の境界を越えて日付を計算するときに役立ちます。つまり、夏時間に参加している場所では、正午から翌日の正午までに25時間ある場合と、正午から翌日の正午まで23時間ある場合があります。時間Aと時間Bからの時間数を正しく決定する場合は、最初にそれぞれをUTC相当に変換してからを計算する必要がありますTimeSpan

これは、私が書いブログ投稿でさらに説明さTimeSpanれており、このトピックに関するさらに広範なMSの記事へのリンクが含まれています。

*説明:どちらの割り当てでも現在の時刻が保存されます。あなたは二つの変数1つを介してロードした場合DateTime.Now()を経由して他の二つの違い時間は、あなたが時間の距離GMTからのタイムゾーンであると仮定していない、ミリ秒単位になります。以下に示すように、それらの値を出力すると、異なる文字列が表示されます。DateTime.UtcNow()TimeSpanString


1
「DateTime.NowまたはDateTime.UtcNowを使用して変数をロードする-割り当ては同じ」について:これを明確にする必要があるかもしれませんか?ここにEDTタイムゾーン(UTC -4)で座っているので、DateTime.UtcNowとDateTime.Nowに2つの変数をそれぞれ割り当て、それらの値をToString()で出力しました。表示される値は4時間離れていて、「同一」ではありません。
Jon Schneider

2
@JonSchneider、私はあなたが正しいと信じています。「割り当ては同一です」という記述は正しくありません。ToString()は、(Javaのように)同じ日付を異なる方法で表示する可能性があるため、それをテストするための最良の方法ではないでしょう。比較関数はより良いテストであり、実際には等しくないことを示しています。
Ted Bigham、2015年

「同一の」ステートメントの明確化:DateTime.Nowを介して1つの変数をロードし、DateTime.UtcNowを使用して別の変数をロードしてから、TimeSpanの違いを出力します。グリニッジ標準時から数時間離れていると仮定すると、差はミリ秒であり、時間ではありません。
Carl Camera

18

これは良い質問です。.NetがさまざまなKind値でどのように動作するかについてもう少し詳しく説明するために、これを復活させます。@Jan Zichが指摘するように、これは実際には非常に重要なプロパティであり、Nowまたはを使用するかどうかによって異なる設定になりますUtcNow

内部的には日付が格納されTicksます(@Carl Cameraの回答とは逆に)は、Nowまたはを使用するかどうかによって異なりますUtcNow

DateTime.UtcNow他の言語と同じように動作します。TicksGMTベースの値に設定します。また、に設定さKindUtcます。

DateTime.NowGMTタイムゾーンでの時刻である場合Ticks値に変更します。また、に設定されます。KindLocal

(GMT-6)より6時間遅れている場合、6時間前のGMT時間を取得します。.Netは実際には無視してKind、6時間前のように扱います。あなたが作成した場合、これはさらに壊れますDateTimeインスタンスてからタイムゾーンを変更してそれを使用しようとするとます。

「種類」の値が異なるDateTimeインスタンスは互換性がありません。

いくつかのコードを見てみましょう...

    DateTime utc = DateTime.UtcNow;
    DateTime now = DateTime.Now;
    Debug.Log (utc + " " + utc.Kind);  // 05/20/2015 17:19:27 Utc
    Debug.Log (now + " " + now.Kind);  // 05/20/2015 10:19:27 Local

    Debug.Log (utc.Ticks);  // 635677391678617830
    Debug.Log (now.Ticks);  // 635677139678617840

    now = now.AddHours(1);
    TimeSpan diff = utc - now;
    Debug.Log (diff);  // 05:59:59.9999990

    Debug.Log (utc <  now);  // false
    Debug.Log (utc == now);  // false
    Debug.Log (utc >  now);  // true

    Debug.Log (utc.ToUniversalTime() <  now.ToUniversalTime());  // true
    Debug.Log (utc.ToUniversalTime() == now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() >  now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() -  now.ToUniversalTime());  // -01:00:00.0000010

ここでわかるように、比較と数学関数は互換時間に自動的に変換されません。のTimespanほぼ1時間あったが、その代わりに、ほぼ6.「UTC <今、」真されている必要があります(私も確かに時間を追加)していたが、さらに虚偽だったはず。

また、どこでも世界標準時に変換する「回避策」も確認できます。 Kind、同じはないます。

質問に対する私の直接の回答は、それぞれをいつ使用するかについての承認された回答の推奨事項に同意します。I / O(表示および解析)中を除いて、常にを持つオブジェクトを操作するようにしてください。つまり、オブジェクトを作成して表示するだけですぐに破棄する場合を除き、ほとんどの場合はを使用する必要があります。DateTimeKind=UtcDateTime.UtcNow


7

DateTimeは、どのタイムゾーンであるかがわかりません。それは常にあなたがあなたの現地時間にいると仮定します。UtcNow単に「時間からタイムゾーンを引く」ことを意味します。

タイムゾーン対応の日付を使用する場合は、タイムゾーンを使用して日付/時刻を表すDateTimeOffsetを使用します。私はそれを難し​​い方法で学ばなければなりませんでした。


9
完全に正確にするには(そしてパフォーマンス上の理由で人々がNow over UtcNowを使用しないようにするため)、それは逆になります:UtcNowにタイムゾーンを追加し、実際には大幅に遅くなります。
mafu

5

質問に対する「単純な」答えは次のとおりです。

DateTime.Nowは、現在のシステム時刻を表すDateTime値を返します(システムが実行されているタイムゾーンで)。DateTime.Kindプロパティは次のようになりますDateTimeKind.Local

DateTime.UtcNowは、現在の協定世界時(別名UTC)を表すDateTime値を返します。これは、システムのタイムゾーンに関係なく同じになります。DateTime.Kindプロパティは次のようになりますDateTimeKind.Utc


4

上記のポイントに少し追加しただけです。DateTime構造体には、Kindと呼ばれるほとんど知られていないフィールドも含まれています(少なくとも、長い間私はそれについて知りませんでした)。これは基本的に、時間が現地時間かUTCかを示す単なるフラグです。現地時間のUTCからの実際のオフセットは指定しません。構造体がどのような意図で構築されたかを示すという事実に加えて、メソッドToUniversalTime()およびToLocalTime()の動作方法にも影響します。



1

DateTime.UtcNowは連続的な単一値の時間スケールですが、DateTime.Nowは連続的または単一値ではありません。主な理由は夏時間であり、UTCには適用されません。したがって、UTCは1時間前後にジャンプすることはありませんが、現地時間(DateTime.Now)はジャンプします。そして、後方にジャンプすると、同じ時間値が2回発生します。


1

DateTime.UtcNowは、夏時間を省略したユニバーサルタイムスケールです。したがって、UTCはDSTのために変更されることはありません。

ただし、DateTime.NowはDSTに従って変化するため、連続的または単一値ではありません。つまり、DateTime.Nowを使用すると、同じ時刻の値が2回発生して、顧客が混乱した状態になる可能性があります。


0

アプリケーションを実行するマシンの現地時間(ヨーロッパのCESTなど)が必要な場合は、Nowを使用してください。ユニバーサルタイムが必要な場合-UtcNow。それは単にあなたの好みの問題です-おそらくあなたが持っている時間を使用したいローカルウェブサイト/スタンドアロンアプリケーションを作る-それで彼/彼女のタイムゾーン設定-DateTime.Nowの影響を受けます。

覚えておいてください、ウェブサイトの場合、それはサーバーのタイムゾーン設定です。したがって、ユーザーの時間を表示している場合は、ユーザーの希望するタイムゾーンを取得して時間をシフトする(Utc時間をデータベースに保存してから変更する)か、またはUTCを指定します。あなたがそうするのを忘れた場合、ユーザーは次のようなものを見ることができます:3マイナス前に投稿されてから、その近くの将来の時間:)


0

大きな違い:)は、DateTime.NowがSharePointワークフローでサポートされていないことです。DateTime.UtcNowを使用する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.