Diferencia entre System.DateTime.Now y System.DateTime.Today

¿Alguien puede explicar la diferencia entre System.DateTime.Now y System.DateTime.Today en C # .NET? Pros y contras de cada uno si es posible.

DateTime.Now devuelve un valor de DateTime que consiste en la fecha y hora local de la computadora donde se ejecuta el código. Tiene DateTimeKind.Local asignado a su propiedad Kind . Es equivalente a llamar a cualquiera de los siguientes:

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

DateTime.Today devuelve un valor de DateTime que tiene los mismos componentes de año, mes y día que cualquiera de las expresiones anteriores, pero con los componentes de tiempo configurados en cero. También tiene DateTimeKind.Local en su propiedad Kind . Es equivalente a cualquiera de los siguientes:

  • 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

Tenga en cuenta que internamente, el reloj del sistema está en términos de UTC, por lo que cuando llama a DateTime.Now obtiene la hora UTC (a través de la función GetSystemTimeAsFileTime en la API de Win32) y luego convierte el valor a la zona horaria local. (Por lo tanto, DateTime.Now.ToUniversalTime() es más caro que DateTime.UtcNow ).

También tenga en cuenta que DateTimeOffset.Now.DateTime tendrá valores similares a DateTime.Now , pero tendrá DateTimeKind.Unspecified lugar de DateTimeKind.Local , lo que podría generar otros errores según lo que haga con él.

Entonces, la respuesta simple es que DateTime.Today es equivalente a DateTime.Now.Date .
Pero, en mi humilde opinión, no debe usar ninguno de estos, ni ninguno de los equivalentes anteriores.

Cuando solicita DateTime.Now , está solicitando el valor del reloj del calendario local de la computadora en la que se está ejecutando el código. ¡Pero lo que recibes no tiene información sobre ese reloj! Lo mejor que se obtiene es DateTime.Now.Kind == DateTimeKind.Local . ¿Pero de quién es el local? Esa información se pierde tan pronto como hace algo con el valor, como almacenarlo en una base de datos, mostrarlo en la pantalla o transmitirlo mediante un servicio web.

Si su zona horaria local sigue las reglas de ahorro de luz diurna, no recuperará esa información de DateTime.Now . En tiempos ambiguos, como durante una transición de “retroceso”, no sabrá cuál de los dos momentos posibles corresponde al valor que recuperó con DateTime.Now . Por ejemplo, supongamos que la zona horaria de su sistema está configurada en Mountain Time (US & Canada) y solicita DateTime.Now en las primeras horas del 3 de noviembre de 2013. ¿Qué significa el resultado 2013-11-03 01:00:00 ? Hay dos momentos de tiempo instantáneo representados por este mismo calendario datetime. Si tuviera que enviar este valor a otra persona, no sabrían a cuál me refería. Especialmente si se encuentran en una zona horaria donde las reglas son diferentes.

Lo mejor que podría hacer sería usar DateTimeOffset lugar:

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

Ahora, para el mismo escenario que describí anteriormente, obtengo el valor 2013-11-03 01:00:00 -0600 antes de la transición, o 2013-11-03 01:00:00 -0700 después de la transición. Cualquiera que mire estos valores puede decir lo que quise decir.

Escribí una publicación de blog sobre este mismo tema. Lea – El caso en contra de DateTime.Now .

Además, hay algunos lugares en este mundo (como Brasil) donde la transición de “spring hacia adelante” ocurre exactamente a la medianoche. Los relojes van de 23:59 a 01:00. Esto significa que el valor que obtienes por DateTime.Today en esa fecha, ¡ no existe! Incluso si usa DateTimeOffset.Now.Date , obtendrá el mismo resultado y aún tendrá este problema. Es porque tradicionalmente, no ha habido tal cosa como un objeto Date en .Net. Entonces, independientemente de cómo obtenga el valor, una vez que se despoje del tiempo, debe recordar que realmente no representa la “medianoche”, aunque ese sea el valor con el que está trabajando.

Si realmente quiere una solución completamente correcta para este problema, el mejor enfoque es usar NodaTime . La clase LocalDate representa correctamente una fecha sin tiempo. Puede obtener la fecha actual para cualquier zona horaria, incluida la zona horaria del sistema local:

 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; 

Si no quiere usar Noda Time, ahora hay otra opción. Contribuí con una implementación de un objeto de fecha única para el proyecto .Net CoreFX Lab . Puede encontrar el objeto del paquete System.Time en su feed MyGet. Una vez agregado a su proyecto, encontrará que puede hacer cualquiera de los siguientes:

 using System; ... Date localDate = Date.Today; Date utcDate = Date.UtcToday; Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject); 

Hora. .Now incluye el 09:23:12 o lo que sea; .Today es la parte de la fecha solamente (a las 00:00:00 de ese día).

Así que usa .Now si quieres incluir la hora, y .Today si solo quieres la fecha!

.Today es esencialmente lo mismo que .Now.Date

La propiedad DateTime.Now devuelve la fecha y la hora actuales, por ejemplo 2011-07-01 10:09.45310 .

La propiedad DateTime.Today devuelve la fecha actual con los comstackdores de tiempo configurados en cero, por ejemplo 2011-07-01 00:00.00000 .

La propiedad DateTime.Today realidad se implementa para devolver DateTime.Now.Date :

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

DateTime.Today representa la fecha del sistema actual con la parte de hora configurada en 00:00:00

y

DateTime.Now representa la fecha y hora actual del sistema

Pensé en Agregar estos enlaces –

  • Una breve historia de DateTime – por Anthony Moore por el equipo de BCL
  • Elegir entre Datetime y DateTime Offset – por MSDN
  • No olvide SQL Server 2008 en adelante tiene un nuevo tipo de datos como DateTimeOffset
  • .NET Framework incluye los tipos DateTime , DateTimeOffset y TimeZoneInfo , todos los cuales se pueden usar para crear aplicaciones que funcionen con fechas y horas.
  • Realización de operaciones aritméticas con fechas y horas: MSDN

Volviendo a la pregunta original, Utilizando Reflector he explicado la diferencia en el código

  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); } } 
 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 

DateTime.Today es DateTime.Now con tiempo establecido en cero.

Es importante observar que hay una diferencia entre un valor de DateTime, que representa el número de ticks que han transcurrido desde la medianoche del 1 de enero de 0000 y la representación de cadena de ese valor de DateTime, que expresa un valor de fecha y hora en un formato específico de la cultura específica: https://msdn.microsoft.com/en-us/library/system.datetime.now%28v=vs.110%29.aspx

DateTime.Now.Ticks es el tiempo real almacenado por .net (esencialmente hora UTC), el rest son solo representaciones (que son importantes para fines de visualización).

Si la propiedad Kind es DateTimeKind.Local , implícitamente incluye la información de zona horaria de la computadora local. Al enviar a través de un servicio web .net, los valores de DateTime se serializan por defecto con la información de zona horaria incluida, por ejemplo, 2008-10-31T15: 07: 38.6875000-05: 00, y una computadora en otra zona horaria todavía puede saber exactamente qué hora es siendo referido.

Entonces, usar DateTime.Now y DateTime.Today está perfectamente bien.

Por lo general, comienza a tener problemas cuando comienza a confundir la representación de cadena con el valor real y trata de “corregir” el DateTime, cuando no está roto.

DateTime.Now.ToShortDateString() solo mostrará la parte de la fecha