System.DateTime.NowとSystem.DateTime.Todayの違い


回答:


179

DateTime.NowDateTimeコードが実行されているコンピューターのローカルの日付と時刻で構成される値を返します。それはしているDateTimeKind.Localのに割り当てられたKindプロパティ。これは、次のいずれかを呼び出すのと同じです。

  • DateTime.UtcNow.ToLocalTime()
  • DateTimeOffset.UtcNow.LocalDateTime
  • DateTimeOffset.Now.LocalDateTime
  • TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local)
  • TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local)

DateTime.TodayDateTime上記の式のいずれかと同じ年、月、日のコンポーネントを持つ値を返しますが、時間コンポーネントはゼロに設定されています。それはまたDateTimeKind.LocalそのKind特性を持っています。次のいずれかに相当します。

  • DateTime.Now.Date
  • DateTime.UtcNow.ToLocalTime().Date
  • DateTimeOffset.UtcNow.LocalDateTime.Date
  • DateTimeOffset.Now.LocalDateTime.Date
  • TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local).Date
  • TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local).Date

内部では、システムクロックはUTCに基づいているため、DateTime.Now最初に呼び出すと(GetSystemTimeAsFileTimeWin32 APIの関数を介して)UTC時間が取得され、次に値がローカルタイムゾーンに変換されます。(したがってDateTime.Now.ToUniversalTime()、よりも高価ですDateTime.UtcNow。)

また、はとDateTimeOffset.Now.DateTime同様の値を持ちますがDateTime.NowDateTimeKind.UnspecifiedではなくDateTimeKind.Local-を持つことに注意してください。これにより、何を行うかによっては他のエラーが発生する可能性があります。

したがって、簡単な答えは、DateTime.Todayと同等DateTime.Now.Dateです。
しかし、私見-これらのいずれか、または上記の同等のもののいずれかを使用しないでください。

を要求する場合DateTime.Now、コードが実行されているコンピューターのローカルカレンダークロックの値を要求しています。しかし、あなたが得るものにはその時計についての情報が何もありません!あなたが得る最高のものはそれDateTime.Now.Kind == DateTimeKind.Localです。しかし、誰の地元ですか?その情報は、データベースに保存したり、画面に表示したり、Webサービスを使用して送信したりするなど、値を操作するとすぐに失われます。

ローカルタイムゾーンが夏時間規則に従っている場合、その情報はから返されませんDateTime.Now。「フォールバック」遷移中などのあいまいな時間では、2つの可能な瞬間のどちらがで取得した値に対応するかがわかりませんDateTime.Now。たとえば、システムのタイムゾーンがに設定されていて、2013年11月3日の早い時間にMountain Time (US & Canada)要求したとしますDateTime.Now。結果は2013-11-03 01:00:00どういう意味ですか?この同じカレンダー日付時刻によって表される瞬間の2つの瞬間があります。この値を誰かに送ったとしても、私が何を意味しているのか誰にもわからないでしょう。特に、ルールが異なるタイムゾーンにいる場合。

あなたができる最善のことはDateTimeOffset代わりに使うことでしょう:

// This will always be unambiguous.
DateTimeOffset now = DateTimeOffset.Now;

上記と同じシナリオで2013-11-03 01:00:00 -0600、遷移前または2013-11-03 01:00:00 -0700遷移後の値を取得します。これらの値を見ている人なら誰でも、私が何を意味しているかがわかります。

私はこの件についてブログ投稿を書きました。お読みください-DateTime.Nowに対する訴訟

また、この世界(ブラジルなど)には、「スプリングフォワード」遷移が真夜中に正確に発生する場所がいくつかあります。時計は23:59から01:00までです。これは、DateTime.Todayその日に取得した値が存在しないことを意味します を使用してもDateTimeOffset.Now.Date、同じ結果が得られ、この問題が依然として発生します。これは、伝統的に、Date.Netにはオブジェクトなどが存在しないためです。したがって、値を取得する方法に関係なく、一度時間を取り除いてください。これは、作業している値であっても、「真夜中」を表すものではないことを覚えておく必要があります。

この問題の完全に正しい解決策が本当に必要な場合、最良のアプローチはNodaTimeを使用することですLocalDateクラスは、適切に時間を除いた日付を表します。ローカルシステムのタイムゾーンを含む、任意のタイムゾーンの現在の日付を取得できます。

using NodaTime;
...

Instant now = SystemClock.Instance.Now;

DateTimeZone zone1 = DateTimeZoneProviders.Tzdb.GetSystemDefault();
LocalDate todayInTheSystemZone = now.InZone(zone1).Date;

DateTimeZone zone2 = DateTimeZoneProviders.Tzdb["America/New_York"];
LocalDate todayInTheOtherZone = now.InZone(zone2).Date;

野田タイムを使いたくない場合は、別のオプションがあります。日付のみのオブジェクトの実装を.Net CoreFX Labプロジェクトに提供しました。System.TimeMyGetフィードでパッケージオブジェクトを見つけることができます。プロジェクトに追加すると、次のいずれかを実行できるようになります。

using System;
...

Date localDate = Date.Today;

Date utcDate = Date.UtcToday;

Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);

9
DateTime.UtcNow代わりにの使用についてはどうDateTimeOffset.Nowですか?
Samuel Liew

5
DateTime.UtcNowアプリケーションまたは仕様で値がUTCであることを伝えることができる場合は許容されます。(実際には、フィールドやプロパティMyDateUtcを単にではなく、次のように呼び出すのが好きですMyDateが、それは単にケーキの上のアイシングです。)スペックまたはフィールド名でそれDateTimeOffset.UtcNowを伝えることができない場合は、ゼロオフセットが確実に伝えられるように使用できます。日付と時刻の値。
Matt Johnson-Pint 2013

それらは等しくありません。今日の時刻は00:00:00です。
James Wilkins

@JamesWilkins-何を取得しているのかわからない。そうDateTime.Now.Dateです。
Matt Johnson-Pint 2015

@MattJohnson問題は、DateTime.TodayとDateTime.Now.Dateではなく、DateTime.TodayとDateTime.Nowの違いです。
デビッドアンダーソン

85

時間。.Now09:23:12などが含まれます。.Today日付部分のみ(その日の00:00:00)。

したがって.Now、時間を含めたい場合、および.Today日付だけが必要な場合に使用してください。

.Today 本質的に同じです .Now.Date


27
... システムのローカルタイムゾーンUtcNow本当に必要な場合を除き、使用します。(特に、ほとんど常に間違った選択であるWebアプリ上で)
Jon Skeet

22

DateTime.Nowプロパティには、例えば、現在の日付と時刻を返します2011-07-01 10:09.45310

このDateTime.Todayプロパティは、たとえば、時刻コンポーネントがゼロに設定された現在の日付を返します2011-07-01 00:00.00000

DateTime.Todayプロパティは、実際に返すために実装されますDateTime.Now.Date

public static DateTime Today {
  get {
    DateTime now = DateTime.Now;
    return now.Date;
  }
}

9

DateTime.Todayは、時間の部分が00:00:00に設定された現在のシステム日付を表します

そして

DateTime.Nowは、現在のシステムの日付と時刻を表します


2
単なる観察... 1.1のドキュメントは4.0のドキュメントほど詳細ではありません。おそらくvLatestにリンクする方が良いですか?
マークグラベル

3
@megaperlz:vLatestではなく4.0にリンクしています。VLatestリンクは、を削除することで作成できます(v=VS.100)
ブライアン

6

これらのリンクを追加することを考えました-

元の質問に戻って、Reflectorを使用して、コードの違いを説明しました

 public static DateTime Today
    {
      get
      {
        return DateTime.Now.Date;   // It returns the date part of Now

        //Date Property
       // returns same date as this instance, and the time value set to 12:00:00 midnight (00:00:00) 
      }
    }


    private const long TicksPerMillisecond = 10000L;
    private const long TicksPerDay = 864000000000L;
    private const int MillisPerDay = 86400000;

    public DateTime Date
    {
       get
      {
        long internalTicks = this.InternalTicks; // Date this instance is converted to Ticks 
        return new DateTime((ulong) (internalTicks - internalTicks % 864000000000L) | this.InternalKind);  
// Modulo of TicksPerDay is subtracted - which brings the time to Midnight time 
      }
    }


     public static DateTime Now
        {
          get
          {
           /* this is why I guess Jon Skeet is recommending to use  UtcNow as you can see in one of the above comment*/
            DateTime utcNow = DateTime.UtcNow;


            /* After this i guess it is Timezone conversion */
            bool isAmbiguousLocalDst = false;
            long ticks1 = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utcNow, out isAmbiguousLocalDst).Ticks;
            long ticks2 = utcNow.Ticks + ticks1;
            if (ticks2 > 3155378975999999999L)
              return new DateTime(3155378975999999999L, DateTimeKind.Local);
            if (ticks2 < 0L)
              return new DateTime(0L, DateTimeKind.Local);
            else
              return new DateTime(ticks2, DateTimeKind.Local, isAmbiguousLocalDst);
          }
        }

5
DateTime dt = new DateTime();// gives 01/01/0001 12:00:00 AM
DateTime dt = DateTime.Now;// gives today date with current time
DateTime dt = DateTime.Today;// gives today date and 12:00:00 AM time

1

DateTime.TodayDateTime.Now時間はゼロに設定されています。

0000年1月1日の午前0時以降に経過したティック数を表すDateTime値と、日付と時刻の値を表すDateTime値の文字列表現には、文化固有の形式:https : //msdn.microsoft.com/en-us/library/system.datetime.now%28v=vs.110%29.aspx

DateTime.Now.Ticks.netによって保存される実際の時間(本質的にはUTC時間)であり、残りは単なる表現です(これは表示の目的で重要です)。

場合はKindプロパティがありDateTimeKind.Local、それは暗黙のうちに、ローカルコンピュータのタイムゾーン情報が含まれています。.net Webサービスを介して送信する場合、DateTime値はデフォルトで、タイムゾーン情報(2008-10-31T15:07:38.6875000-05:00など)を使用してシリアル化され、別のタイムゾーンのコンピューターでも正確に何時かを知ることができます。参照されています。

したがって、DateTime.NowとDateTime.Todayを使用してもまったく問題ありません。

通常、文字列表現と実際の値を混同し始めて、壊れていないときにDateTimeを「修正」しようとすると、問題が発生し始めます。


-1

DateTime.Now.ToShortDateString() 日付部分のみを表示します

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