Me he estado preguntando cuáles son exactamente los principios de cómo funcionan las dos propiedades. Sé que la segunda es universal y, básicamente, no tiene que ver con las zonas horarias, pero ¿alguien puede explicar en detalle cómo funcionan y cuál se debe usar en qué escenario?
DateTime.UtcNow le indica la fecha y la hora tal como sería en la Hora Universal Coordinada, que también se conoce como la zona horaria de Greenwich Mean Time, básicamente como si estuviera en Londres, Inglaterra, pero no durante el verano. . DateTime.Now da la fecha y la hora como aparecería a alguien en su ubicación actual.
Recomiendo usar DateTime.Now
siempre que le muestres una cita a un ser humano, de esa manera se sienten cómodos con el valor que ven, es algo que pueden comparar fácilmente con lo que ven en su reloj o reloj. Utilice DateTime.UtcNow
cuando desee almacenar fechas o utilícelas para cálculos posteriores de esa manera (en un modelo cliente-servidor) sus clientes no confundirán los cálculos en diferentes zonas horarias de su servidor o entre sí.
Realmente es bastante simple, así que creo que depende de lo que tu audiencia es y dónde viven.
Si no usa Utc, debe debe conocer la zona horaria de la persona con la que está mostrando las fechas y las horas, de lo contrario, le dirá que sucedió a las 3 PM en el sistema o servidor tiempo, cuando realmente sucedió a las 5 PM donde viven.
Usamos DateTime.UtcNow
porque tenemos una audiencia web global, y porque prefiero no molestar a todos los usuarios para que completen un formulario que indique en qué zona horaria viven.
También mostramos los tiempos relativos (hace 2 horas, hace 1 día, etc.) hasta que la publicación sea lo suficientemente larga como para que el tiempo sea "el mismo", sin importar en qué lugar de la Tierra viva.
También tenga en cuenta la diferencia de rendimiento; DateTime.UtcNow es en algún lugar alrededor de 30 veces más rápido que DateTime.Now, porque DateTime.Now internamente está haciendo muchos ajustes de zona horaria (puede verificarlo fácilmente con Reflector).
Así que no use DateTime. Ahora para mediciones de tiempo relativas.
Un concepto principal a entender en .NET es que ahora es ahora en toda la tierra, sin importar en qué zona horaria se encuentre. Por lo tanto, si carga una variable con DateTime.Now
o DateTime.UtcNow
- la asignación es idéntica. * Su objeto DateTime
sabe en qué zona horaria está y lo tiene en cuenta independientemente de la asignación.
La utilidad de DateTime.UtcNow
es útil cuando se calculan fechas entre los límites del horario de verano. Es decir, en lugares que participan en el horario de verano, a veces hay 25 horas desde el mediodía hasta el mediodía del día siguiente, y a veces hay 23 horas entre el mediodía y el mediodía del día siguiente. Si desea determinar correctamente la cantidad de horas desde el tiempo A y el tiempo B, primero debe traducir cada uno a sus equivalentes UTC antes de calcular la TimeSpan
.
Esto está cubierto por una publicación de blog que escribí que explica más detalladamente TimeSpan
, e incluye un enlace a un artículo de MS aún más extenso sobre el tema.
* Aclaración: Cualquiera de las asignaciones almacenará la hora actual. Si tuviera que cargar dos variables, una a través de DateTime.Now()
y la otra a través de DateTime.UtcNow()
, la diferencia de TimeSpan
entre las dos sería de milisegundos, no de horas, suponiendo que se encuentre en una zona horaria a horas de GMT. Como se indica a continuación, la impresión de sus valores de String
mostraría diferentes cadenas.
Esta es una buena pregunta. Lo estoy reviviendo para dar un poco más de detalles sobre cómo se comporta .Net con diferentes valores de Kind
. Como lo señala @Jan Zich, en realidad es una propiedad de importancia crítica y se establece de manera diferente según se use Now
o UtcNow
.
Internamente, la fecha se almacena como Ticks
, que (a diferencia de la respuesta de @Carl Camera) es diferente dependiendo de si usa Now
o UtcNow
.
DateTime.UtcNow
se comporta como otros idiomas. Establece Ticks
a un valor basado en GMT. También establece Kind
a Utc
.
DateTime.Now
altera el valor de Ticks
a lo que sería si fuera su hora del día en la zona horaria GMT . También establece Kind
a Local
.
Si tiene 6 horas de retraso (GMT-6), obtendrá la hora GMT de hace 6 horas. .Net en realidad ignora Kind
y trata esta vez como si fuera hace 6 horas, a pesar de que se supone que es "ahora". Esto se rompe aún más si creas una instancia de DateTime
, luego cambias tu zona horaria y tratas de usarla.
Las instancias de DateTime con diferentes valores 'Tipo' NO son compatibles.
Veamos un código ...
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
Como puede ver aquí, las comparaciones y las funciones matemáticas no se convierten automáticamente a tiempos compatibles. La Timespan
debería haber sido casi una hora, pero en lugar de casi 6. "utc <now" debería haber sido cierta (incluso añadí una hora para estar segura), pero aún así era falsa.
También puede ver la "solución alternativa" que consiste simplemente en convertir a la hora universal en cualquier lugar que Kind
no sea lo mismo.
Mi respuesta directa a la pregunta concuerda con la recomendación de la contestadora aceptada sobre cuándo usar cada una. Siempre debe probar para trabajar con DateTime
objetos que tienen Kind=Utc
, excepto durante i/o (visualización y análisis). Esto significa que casi siempre debería estar usando DateTime.UtcNow
, excepto en los casos en que está creando el objeto solo para mostrarlo y descartarlo de inmediato.
DateTime no tiene idea de qué son las zonas horarias. Siempre asume que estás en tu hora local. UtcNow solo significa "Restar mi zona horaria del tiempo".
Si desea usar fechas que tengan en cuenta la zona horaria, use DateTimeOffset , que representa una fecha/hora con una zona horaria. Tuve que aprender eso de la manera más difícil.
La respuesta "simple" a la pregunta es:
DateTime.Now devuelve un DateTime valor que representa la hora actual del sistema (en cualquier zona horaria en la que se esté ejecutando el sistema). La propiedad DateTime.Kind será DateTimeKind.Local
DateTime.UtcNow devuelve un DateTime value que representa el Tiempo Universal Coordinado actual (también conocido como UTC) que será el mismo independientemente de la zona horaria del sistema. La propiedad DateTime.Kind será DateTimeKind.Utc
Solo una pequeña adición a los puntos mencionados anteriormente: la estructura DateTime también contiene un campo poco conocido llamado Tipo (al menos, no lo sabía desde hace mucho tiempo). Básicamente es solo una bandera que indica si la hora es local o UTC; no especifica el desplazamiento real de UTC para las horas locales. Además del hecho de que indica con qué intenciones se construyó la estructura, también influye en cómo funcionan los métodos ToUniversalTime () y ToLocalTime () .
Un poco tarde para la fiesta, pero encontré que estos dos enlaces (4guysfromrolla) son muy útiles:
Uso de la hora universal coordinada (UTC) para almacenar valores de fecha/hora
Consejos para almacenar y mostrar fechas y horas en diferentes zonas horarias
DateTime.UtcNow es una escala de tiempo continua de un solo valor, mientras que DateTime.Now no es continua ni de un solo valor. El motivo principal es el horario de verano, que no se aplica a UTC. Por lo tanto, UTC nunca salta ni retrocede una hora, mientras que la hora local (DateTime.Now) sí lo hace. Y cuando salta hacia atrás, el mismo valor de tiempo ocurre dos veces.
DateTime.UtcNow es una escala de tiempo universal que omite el horario de verano. Así que UTC nunca cambia debido a DST.
Pero, DateTime.Now no es continuo ni de un solo valor porque cambia de acuerdo con el DST. Lo que significa DateTime. Ahora, el mismo valor de tiempo puede ocurrir dos veces dejando a los clientes en un estado de confusión.
Cuando necesite una hora local para la máquina en la que se ejecuta su aplicación (como CEST para Europa), use Ahora. Si quieres un tiempo universal - UtcNow. Es solo una cuestión de sus preferencias: probablemente cree un sitio web local o una aplicación independiente que quiera usar la hora que el usuario tiene, tan afectado por su configuración de zona horaria: DateTime.Now.
Solo recuerde, para un sitio web es la configuración de zona horaria del servidor. Entonces, si está mostrando el tiempo para el usuario, obtenga su zona horaria preferida y cambie el tiempo (solo guarde el tiempo de Utc en la base de datos y modifíquelo) o especifique su UTC. Si olvida hacerlo, el usuario puede ver algo como: publicado hace 3 minutos y luego una hora en el futuro cerca :)