2008-09-15 14 views
160

私は、2つのプロパティの仕組みの原理が正確に何であるか疑問に思っています。私は第2のものが普遍的で、基本的にタイムゾーンを扱っていないことを知っていますが、誰かがどのように働いているのか、どのシナリオでどのようなシナリオを使うべきかを詳しく説明できますか?DateTime.NowとDateTime.UtcNow

+1

が遅すぎるかもしれませんが、私はこのブログを指したいと思います:http://blog.angeloflogic.com/2013/10/nlog-timestamps-with-millisecond.html –

+0

小さなベンチマークhttp:// rextester。 com/QRDR82396 –

答えて

260

DateTime.UtcNowは、世界標準時(グリニッジ標準時)とも呼ばれる日時を示しています。基本的には、ロンドンのイングランドにあったのと同じですが、夏にはそうではありません。 DateTime.Nowは、現在のロケールの誰かに表示される日時を返します。

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

+63

優れた点 - データベースまたはファイルに*日付を保存するときは、間違いなくUTCに保存してください! –

+10

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

+0

@OmervanKloetenは非常に良い点を与えます。私は、あなたのIISとSQLサーバーが異なるタイムゾーンにある場合でも、毎回正確に日付を格納して受け取るためのエレガントな「オールラウンド」ソリューションがあるかどうか疑問に思っています。 – TheGeekZn

71

これは本当にシンプルなので、視聴者とはどこに住んでいるのかによって異なります。

Utcを使用しない場合は、に、日付と時刻を表示する人のタイムゾーンを知っている必要があります。そうしないと、システムまたはサーバーの時刻に午後3時に起きたことを通知します。実際に起こったのは午後5時だった。

我々はグローバルウェブ聴衆を持っているので、私は彼らが住んでどのようなタイムゾーンを示すフォームに必要事項を記入するすべてのユーザーにガミガミ希望しませんので、我々は DateTime.UtcNowを使用しています。

我々はまた、相対時間(2時間を表示

あなたが地球上のどこに住んでいても、時間は "同じ"です。

+0

Iまた、DateTime.UtcNowを格納することは、正しい日付を得るために2つの日付の計算が行われた場合にのみ必要です。 RegisterAt Dateを表示するだけで、Datetime.Nowで十分です。 – Elisabeth

1

アプリケーションが動作するマシン(ヨーロッパの場合はCESTなど)にローカルタイムが必要な場合は、Nowを使用します。普遍的な時間が必要な場合 - UtcNow。それはあなたの好みの問題です - おそらくローカルWebサイト/スタンドアロンアプリケーションを作成して、ユーザーの時間を使いたいと思っています - そのためタイムゾーンの設定 - DateTime.Nowの影響を受けます。

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

6

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

タイムゾーン対応の日付を使用する場合は、DateTimeOffsetを使用します。これは、タイムゾーンを持つ日付/時刻を表します。私はその難しい方法を学ばなければならなかった。 。NETで理解する

+7

完全に正確である(そしてパフォーマンス上の理由からNow UtcNowを使用しないようにする)ために、これは逆です:NowはUtcNowにタイムゾーンを追加し、実際にはより低速です。 – mafu

24

一つのメインコンセプトは、が今は今全地の上に関係なく、あなたが何であるかを時間帯であることをあなたがDateTime.NowまたはDateTime.UtcNowを持つ変数を読み込む場合はそうです - *あなたのDateTimeオブジェクトは、あなたがどのタイムゾーンにいるのかを知っていて、割り当てにかかわらず考慮しています。

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

これはでカバーされており、さらにTimeSpanについて説明しており、このトピックに関するさらに詳しいMS記事へのリンクも含まれています。

*明確化:どちらの割り当てでも現在の時刻が保存されます。 DateTime.Now()とDateTime.UtcNow()を介して2つの変数をロードする場合、2つの変数の時間差はミリ秒になります。GMTから離れた時間帯にいると仮定した時間はミリ秒です。後述するように、文字列値を出力すると、異なる文字列が表示されます。

+1

"DateTime.NowまたはDateTimeで変数をロードすることについて。私はここでEDTタイムゾーン(UTC -4)に座っているので、DateTime.UtcNowとDateTime.Nowにそれぞれ2つの変数を割り当てて、その値を次のように出力しました。 ToString()。表示された値は4時間離れていますが、 "同一"ではありません。 –

+2

@JonSchneider、私はあなたが正しいと信じています。 –

+0

"同一の"ステートメントへの明確化:DateTime.Nowを介して1つの変数を読み込みます(これは、Javaのように同じ日付を別々に表示できるためです)。もう1つはDateTime.UtcNowで、次にTimeSpanの差を表示します。差はミリ秒で、GMTから何時間も離れていないと仮定して時間はありません。 –

21

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

相対時間測定にはDateTime.Nowを使用しないでください。

4

DateTime構造体には、Kindと呼ばれる少し知られているフィールドが含まれています(少なくとも私はそれについて長いこと知らなかった)。基本的には時刻がローカルかUTCかを示すフラグです。現地時間のUTCからの実際のオフセットを指定していません。それがどのような意図が構築されたかを示すという事実に加えて、方法ToUniversalTime()ToLocalTime()がどのように機能するかにも影響します。

少し遅れて相手に
2

「簡単な」答えは次のとおりです。

DateTime.Nowは何で(現在のシステム時刻を表す日時値を返しますシステムが実行されている時間帯があります)。 DateTime.Kind性にかかわらず、システムの同じになり、電流ユニバーサル協調時間(別名UTC)を表す日時値を返しDateTimeKind.Local

DateTime.UtcNowあろうタイムゾーン。 DateTime.KindプロパティはDateTimeKind.Utc

1

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

12

これは良い質問です。私はそれを復活させて、少し詳しく説明します。ネットは異なる「種類」の値で動作します。 @Jan Zichが指摘するように、実際には非常に重要なプロパティで、NowやUtcNowのどちらを使用するかによって、設定が異なります。

内部的に、日付は「Now」または「UtcNow」を使用するかどうかによって(@ Carl Cameraの回答とは異なり)「刻み」として保存されます。

DateTime.UtcNowは他の言語と同様に動作します。 TicksはGMTベースの値に設定されます。また、 'Kind'を 'Utc'に設定します。

DateTime.Nowは、GMTタイムゾーンの時刻であれば、Ticksの値をに変更します。また、「Kind」を「Local」に設定します。

6時間(GMT-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 

...のは、いくつかのコードを見てみましょう。タイムスパンはほぼ1時間だったはずですが、代わりにほぼ6でした。「utc <今」は本当だったはずです(確かに1時間も追加しました)が、まだ間違っていました。

「回避」は、「種類」が同じでない任意の世界時に変換することもできます。

質問に対する私の直接の答えは、それぞれの答えをいつ使用するかについての受け入れられた回答の推奨に同意します。 は、I/O(表示と解析)の間を除いて、Kind = Utcを持つDateTimeオブジェクトで作業するようにしてください。つまり、オブジェクトを作成して表示するだけの場合を除いて、ほとんどの場合、DateTime.UtcNowを使用する必要があります。すぐに破棄してください。

関連する問題