私は、2 つのプロパティがどのように機能するかの原則が正確に何であるか疑問に思っていました。2番目のものは普遍的であり、基本的にタイムゾーンを扱っていないことは知っていますが、誰かがそれらがどのように機能し、どのシナリオで使用する必要があるかを詳細に説明できますか?
13 に答える
DateTime.UtcNowは、協定世界時と同じように日付と時刻を示します。これは、グリニッジ標準時タイムゾーンとも呼ばれます。基本的には、イギリスのロンドンにいる場合と同じですが、夏の間はそうではありません。DateTime.Nowは、現在のロケールの誰かに表示される日付と時刻を示します。
人間に日付を表示するときはいつでも使用することをお勧めしDateTime.Now
ます-そうすれば、彼らが見る価値に満足します-それは彼らが時計や時計で見るものと簡単に比較できるものです。日付を保存したり、後で計算に使用したりする場合に使用DateTime.UtcNow
します(クライアント/サーバーモデルで)。サーバーまたは相互に異なるタイムゾーンのクライアントが計算を混乱させないようにします。
とてもシンプルなので、聴衆が何で、どこに住んでいるかによると思います。
UTCを使用しない場合は、日付と時刻を表示している人のタイムゾーンを知っている必要があります。そうでない場合は、システム時間またはサーバー時間の午後3時に何かが発生したことを伝えます。実際には、午後5時に発生しました。彼らはたまたま生きています。
私たちが使用DateTime.UtcNow
しているのは、世界中のWebオーディエンスがいて、すべてのユーザーがどのタイムゾーンに住んでいるかを示すフォームに記入するようにせがむことを望まないためです。
また、地球上のどこに住んでいても時間が「同じ」になるように投稿が十分に古くなるまでの相対時間(2時間前、1日前など)も表示します。
また、パフォーマンスの違いにも注意してください。DateTime.UtcNow
これは、内部で多くのタイムゾーン調整が行われているためです (これはReflectorで簡単に確認できます) 。DateTime.Now
DateTime.Now
DateTime.Now
したがって、相対時間の測定には使用しないでください。
.NET で理解すべき主な概念の 1 つは、現在のタイム ゾーンに関係なく、現在は地球全体にあるということです。したがって、変数をorでロードすると、代入は同じになります。オブジェクトは、現在のタイム ゾーンを認識します。割り当てに関係なく、それを考慮に入れます。DateTime.Now
DateTime.UtcNow
DateTime
の有用性はDateTime.UtcNow
、夏時間の境界を越えて日付を計算するときに役立ちます。つまり、サマータイムに参加している場所では、正午から翌日の正午までが 25 時間の場合もあれば、正午から翌日の正午までが 23 時間の場合もあります。時刻 A と時刻 B からの時間数を正確に判断するには、まず、時間を計算する前に、それぞれを UTC に換算する必要がありますTimeSpan
。
これは、私が書いたブログ投稿でカバーされており、さらに詳しく説明してTimeSpan
おり、このトピックに関するさらに広範な MS 記事へのリンクが含まれています。
*明確化: どちらの割り当ても現在の時刻を保存します。2 つの変数を 1 つを介してロードDateTime.Now()
し、もう1 つを介してロードする場合、2 つの変数DateTime.UtcNow()
のTimeSpan
差はミリ秒であり、GMT から数時間離れたタイムゾーンにいると仮定すると、時間ではありません。以下に示すように、それらのString
値を出力すると、異なる文字列が表示されます。
これは良い質問です。.Net がさまざまな値でどのように動作するかについてもう少し詳しく説明するために、それを復活させていKind
ます。@Jan Zichが指摘しているように、これは実際には非常に重要なプロパティであり、Now
またはを使用するかどうかによって設定が異なりますUtcNow
。
内部的には、日付は (@Carl Camera の回答に反して) どちらとして保存され、またはTicks
を使用するかによって異なります。 Now
UtcNow
DateTime.UtcNow
他の言語のように振る舞います。Ticks
GMT ベースの値に設定されます。にも設定Kind
しUtc
ます。
DateTime.Now
GMT タイム ゾーンの時刻である場合Ticks
の値に値を変更します。にも設定します。Kind
Local
6 時間遅れている場合 (GMT-6)、6 時間前の GMT 時刻を取得します。.Net は実際にKind
はこの時間を無視し、「今」であるはずなのに、6 時間前であるかのように扱います。DateTime
インスタンスを作成してからタイムゾーンを変更して使用しようとすると、これはさらに壊れます。
'Kind' 値が異なる 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 時間のTimespan
はずでしたが、ほぼ 6 時間でした。「utc < now」は true である必要がありました (確かに 1 時間も追加しました) が、それでも false でした。
Kind
また、同じではない場所を世界時に単純に変換する「回避策」も確認できます。
質問に対する私の直接の回答は、それぞれをいつ使用するかについての受け入れられた回答の推奨事項に同意します。i/o (表示と解析) 中を除いて、常にを持つオブジェクトを操作するようにしてください。これは、表示するためだけにオブジェクトを作成し、すぐに破棄する場合を除いて、ほとんど常に を使用する必要があることを意味します。DateTime
Kind=Utc
DateTime.UtcNow
DateTimeは、タイムゾーンが何であるかを認識していません。それは常にあなたがあなたの現地時間にいることを前提としています。UtcNowは、「時間から私のタイムゾーンを引く」という意味のみを意味します。
タイムゾーン対応の日付を使用する場合は、DateTimeOffsetを使用します。これは、タイムゾーンで日付/時刻を表します。私はそれを難しい方法で学ばなければなりませんでした。
質問に対する「簡単な」答えは次のとおりです。
DateTime.Nowは、現在のシステム時刻(システムが実行されているタイムゾーン)を表すDateTime値を返します。DateTime.KindプロパティはDateTimeKind.Localになります
DateTime.UtcNowは、システムのタイムゾーンに関係なく同じになる現在の協定世界時(別名UTC)を表すDateTime値を返します。DateTime.KindプロパティはDateTimeKind.Utcになります
上記のポイントに少し追加します。DateTime 構造体には、Kindという名前のあまり知られていないフィールドも含まれています(少なくとも、私は長い間そのことを知りませんでした)。これは基本的に、時刻が現地時間か UTC かを示す単なるフラグです。現地時間の UTC からの実際のオフセットは指定しません。スタックが構築された意図を示すという事実に加えて、メソッドToUniversalTime()およびToLocalTime()の動作方法にも影響します。
パーティーには少し遅れましたが、次の 2 つのリンク (4guysfromrolla) が非常に役立つことがわかりました。
アプリケーションを実行するマシンの現地時間を必要とする場合(ヨーロッパのCESTなど)、[今すぐ]を使用します。普遍的な時間を望むなら-UtcNow。それはあなたの好みの問題です-おそらくあなたがユーザーが持っている時間を使いたいローカルウェブサイト/スタンドアロンアプリケーションを作る-それで彼/彼女のタイムゾーン設定-DateTime.Nowの影響を受けます。
Webサイトの場合、サーバーのタイムゾーン設定であることを覚えておいてください。したがって、ユーザーの時刻を表示している場合は、ユーザーの好みのタイムゾーンを取得して時刻をシフトするか(UTC時間をデータベースに保存して変更するだけ)、UTCを指定します。そうするのを忘れた場合、ユーザーは次のようなものを見ることができます:3マイナス前に投稿され、その後その近くにある時間:)
DateTime.UtcNow は連続した単一値のタイム スケールですが、DateTime.Now は連続的でも単一値でもありません。主な理由は、UTC には適用されない夏時間です。したがって、UTC は 1 時間前後にジャンプすることはありませんが、現地時間 (DateTime.Now) はジャンプします。逆方向にジャンプすると、同じ時間値が 2 回発生します。