Разница между System.DateTime.Now и System.DateTime.Today

Может ли кто-нибудь объяснить разницу между System.DateTime.Now и System.DateTime.Today в С#.NET? Плюсы и минусы каждого, если это возможно.

Ответ 1

DateTime.Now возвращает значение DateTime, которое состоит из локальной даты и времени компьютера, на котором выполняется код. Он имеет 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.Today возвращает значение DateTime, которое имеет те же компоненты year, month и day как любое из приведенных выше выражений, но с компонентами времени, установленными на ноль. Он также имеет 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, он сначала получает время UTC (через GetSystemTimeAsFileTime в Win32 API), а затем преобразует значение в локальный часовой пояс. (Поэтому DateTime.Now.ToUniversalTime() дороже, чем DateTime.UtcNow.)

Также обратите внимание, что DateTimeOffset.Now.DateTime будет иметь схожие значения с DateTime.Now, но у него будет DateTimeKind.Unspecified, а не DateTimeKind.Local - что может привести к другим ошибкам в зависимости от того, что вы с ним сделаете.

Итак, простой ответ: DateTime.Today эквивалентен DateTime.Now.Date.
Но ИМХО. Вы не должны использовать ни один из них, ни любой из вышеперечисленных эквивалентов.

Когда вы запрашиваете DateTime.Now, вы запрашиваете значение локальных часов календаря на компьютере, на котором работает этот код. Но то, что вы получаете, не имеет никакой информации об этих часах! Лучшее, что вы получаете, это DateTime.Now.Kind == DateTimeKind.Local. Но чей это локальный? Эта информация теряется, как только вы делаете что-либо со значением, например, сохраняете его в базе данных, отображаете на экране или передаете его с помощью веб-службы.

Если ваш локальный часовой пояс соответствует правилам перехода на летнее время, вы не получите эту информацию из DateTime.Now. В неоднозначные моменты, например, во время перехода "назад", вы не будете знать, какой из двух возможных моментов соответствует значению, которое вы получили с помощью DateTime.Now. Например, предположим, что для вашего часового пояса системы установлено значение Mountain Time (US & Canada), и вы запрашиваете DateTime.Now в ранние часы 3 ноября 2013 года. Что означает результат 2013-11-03 01:00:00? Есть два момента мгновенного времени, представленных этим самым календарем datetime. Если бы я послал это значение кому-то другому, они бы понятия не имели, что я имел в виду. Особенно, если они находятся в часовом поясе, где правила разные.

Лучшее, что вы могли бы сделать, это использовать вместо 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.

Кроме того, в этом мире есть места (например, Бразилия), где переход "spring -forward" происходит точно в полночь. Часы идут с 23:59 до 01:00. Это означает, что значение, которое вы получаете за DateTime.Today в эту дату, не существует! Даже если вы используете DateTimeOffset.Now.Date, вы получаете тот же результат, и у вас все еще есть эта проблема. Это потому, что традиционно в .NET не было объекта 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;

Если вы не хотите использовать Noda Time, теперь есть еще один вариант. Я внедрил реализацию объекта только для даты в проект

Ответ 2

Время. .Now включает в себя 09:23:12 или что-то еще; .Today - только дата-часть (в 00:00:00 в этот день).

Поэтому используйте .Now, если вы хотите включить время, и .Today, если вам нужна дата!

.Today по существу совпадает с .Now.Date

Ответ 3

Свойство 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;
  }
}

Ответ 4

DateTime.Today представляет текущую системную дату с временной частью, установленной на 00:00:00

и

DateTime.Now представляет текущую системную дату и время

Ответ 5

Я думал о добавлении этих ссылок -

Возвращаясь к исходному вопросу, используя 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);
          }
        }

Ответ 6

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

Ответ 7

DateTime.Today DateTime.Now со временем, установленным на ноль.

Важно отметить, что существует разница между значением DateTime, которое представляет количество тиков, прошедших с полуночи 1 января 0000 года, и строковое представление этого значения 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 значения DateTime по умолчанию сериализуются с включенной информацией о часовом поясе, например. 2008-10-31T15: 07: 38.6875000-05: 00, а компьютер в другом часовом поясе все еще может точно знать, на что время ссылается.

Итак, используя DateTime.Now и DateTime.Today отлично.

Обычно вы начинаете запутываться, когда начинаете путать строковое представление с фактическим значением и пытаетесь "исправить" DateTime, когда оно не сломано.