¿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 DateTime
valor que consiste en la fecha y hora local de la computadora donde se ejecuta el código. Se ha DateTimeKind.Local
asignado a su Kind
propiedad. 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 DateTime
valor que tiene los mismos componentes de año, mes y día que cualquiera de las expresiones anteriores, pero con los componentes de tiempo establecidos en cero. También tiene DateTimeKind.Local
en su Kind
propiedad. 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 lo llama DateTime.Now
primero obtiene la hora UTC (a través de la GetSystemTimeAsFileTime
función en la API Win32) y luego convierte el valor a la zona horaria local. (Por DateTime.Now.ToUniversalTime()
lo tanto, 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
más que DateTimeKind.Local
- lo que podría conducir a otros errores dependiendo de 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
, solicita el valor del reloj de calendario local de la computadora en la que se ejecuta el código. ¡Pero lo que obtienes no tiene información sobre ese reloj! Lo mejor que obtienes es eso 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 alguna regla de horario de verano, no obtiene esa información DateTime.Now
. En tiempos ambiguos, como durante una transición "alternativa", no sabrá cuál de los dos posibles momentos corresponde al valor con el que recuperó DateTime.Now
. Por ejemplo, supongamos que la zona horaria de su sistema está configurada Mountain Time (US & Canada)
y lo 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 fecha y hora. Si tuviera que enviar este valor a otra persona, no tendrían idea de a qué me refería. Especialmente si están en una zona horaria donde las reglas son diferentes.
Lo mejor que podría hacer sería usar DateTimeOffset
en su 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. Por favor lea - El caso contra DateTime . Ahora .
Además, hay algunos lugares en este mundo (como Brasil) donde la transición "hacia adelante" ocurre exactamente a la medianoche. Los relojes van desde las 23:59 hasta la 01:00. ¡Esto significa que el valor que obtienes DateTime.Today
en esa fecha no existe! Incluso si lo usa DateTimeOffset.Now.Date
, está obteniendo el mismo resultado y todavía tiene este problema. Es porque tradicionalmente, no ha habido un Date
objeto en .Net. Entonces, independientemente de cómo obtenga el valor, una vez que se quita el tiempo, debe recordar que realmente no representa la "medianoche", aunque ese es el valor con el que está trabajando.
Si realmente desea una solución completamente correcta para este problema, el mejor enfoque es usar NodaTime . La LocalDate
clase representa correctamente una fecha sin hora. 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 desea utilizar Noda Time, ahora hay otra opción. He contribuido con una implementación de un objeto de solo fecha al proyecto .Net CoreFX Lab . Puede encontrar el System.Time
objeto del paquete en su feed MyGet. Una vez agregado a su proyecto, encontrará que puede hacer lo siguiente:
using System;
...
Date localDate = Date.Today;
Date utcDate = Date.UtcToday;
Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);
DateTime.UtcNow
lugar deDateTimeOffset.Now
?DateTime.UtcNow
es aceptable si puede transmitir en su solicitud o especificación que el valor está en UTC. (Me gusta llamar al campo o la propiedad algo así como enMyDateUtc
lugar de simplementeMyDate
, pero eso es solo la guinda del pastel). Si no puede transmitirlo en la especificación o el nombre del campo,DateTimeOffset.UtcNow
puede usarse para garantizar que se transmita el desplazamiento cero. con los valores de fecha y hora.DateTime.Now.Date
.Hora.
.Now
incluye el 09:23:12 o lo que sea;.Today
es la parte de fecha solamente (a las 00:00:00 de ese día).¡Úselo
.Now
si desea incluir la hora y.Today
si solo desea la fecha!.Today
es esencialmente lo mismo que.Now.Date
fuente
UtcNow
menos que realmente desee la zona horaria local del sistema. (En particular, en una aplicación web que casi siempre es la elección incorrecta.)La
DateTime.Now
propiedad devuelve la fecha y hora actuales, por ejemplo2011-07-01 10:09.45310
.La
DateTime.Today
propiedad devuelve la fecha actual con los componentes de tiempo establecidos en cero, por ejemplo2011-07-01 00:00.00000
.La
DateTime.Today
propiedad en realidad se implementa para devolverDateTime.Now.Date
:fuente
DateTime.Today representa la fecha actual del sistema con la parte de tiempo establecida en 00:00:00
y
DateTime.Now representa la fecha y hora actuales del sistema
fuente
(v=VS.100)
.Pensé en agregar estos enlaces:
Volviendo a la pregunta original, usando Reflector he explicado la diferencia en el código
fuente
fuente
DateTime.Today
esDateTime.Now
con el tiempo establecido en cero.Es importante tener en cuenta que hay una diferencia entre un valor DateTime, que representa el número de tics que han transcurrido desde la medianoche del 1 de enero de 0000, y la representación de cadena de ese valor DateTime, que expresa un valor de fecha y hora en un formato específico de 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 resto son solo representaciones (que son importantes para fines de visualización).Si la
Kind
propiedad esDateTimeKind.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 de manera predeterminada con información de zona horaria incluida, por ejemplo, 2008-10-31T15: 07: 38.6875000-05: 00, y una computadora en otra zona horaria aún puede saber exactamente qué hora es siendo referidoEntonces, 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 e intenta "arreglar" el DateTime, cuando no está roto.
fuente
DateTime.Now.ToShortDateString()
mostrará solo la parte de la fechafuente