DateTime.Ahora contra DateTime.UtcNow


Me he estado preguntando cuáles son exactamente los principios de cómo funcionan las dos propiedades. Sé que el segundo es universal y básicamente no se ocupa de las zonas horarias, pero ¿puede alguien explicar en detalle cómo funcionan y cuál debe usarse en qué escenario?

Author: Jedi Master Spooky, 2008-09-15

12 answers

DateTime.UtcNow te dice la fecha y la hora tal como sería en la Hora Universal Coordinada, que también se llama la zona horaria del Meridiano de Greenwich, básicamente como lo sería si estuvieras en Londres, Inglaterra, pero no durante el verano. DateTime.Ahora da la fecha y la hora como le parecería a alguien en su configuración regional actual.

Yo recomendaría usar DateTime.Now cada vez que usted está mostrando una fecha 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. Use DateTime.UtcNow cuando quiera almacenar fechas o usarlas para cálculos posteriores de esa manera (en un modelo cliente-servidor) sus cálculos no se confundan con clientes en diferentes zonas horarias de su servidor o entre sí.

 277
Author: Blair Conrad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-18 20:44:48

Es realmente bastante simple, así que creo que depende de cuál es tu audiencia y dónde vive.

Si no usas Utc, debes conocer la zona horaria de la persona a la que estás mostrando fechas y horas to de lo contrario, les dirás que algo sucedió a las 3 PM en la hora del sistema o del servidor, cuando realmente sucedió a las 5 PM donde viven.

Usamos DateTime.UtcNow porque tenemos una audiencia web global, y porque preferiría no molestar a todos los usuarios para que llenen un formulario indicando en qué zona horaria viven.

También mostramos los tiempos relativos (hace 2 horas, hace 1 día, etc.) hasta que el post envejece lo suficiente como para que el tiempo sea "el mismo" sin importar en qué parte de la Tierra vivas.

 73
Author: Jeff Atwood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-15 11:03:36

Un concepto principal para entender en.NET es que ahora es ahora por toda la tierra sin importar en qué zona horaria se encuentre. Así que si carga una variable con DateTime.Ahora o DateTime.UtcNow the la asignación es idéntica.* El objeto DateTime sabe en qué zona horaria se encuentra y lo tiene en cuenta independientemente de la asignación.

La utilidad de DateTime.UtcNow es útil al calcular fechas a través de los límites de horario de verano. Es decir, en lugares que participar 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 el número de horas desde el tiempo A y el tiempo B, primero debe traducir cada uno a sus equivalentes UTC antes de calcular el intervalo de tiempo.

Esto está cubierto por una entrada de blog que escribí que explica más a fondo el intervalo de tiempo 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 vía DateTime.Now () y la otra vía DateTime.UtcNow() la diferencia de intervalo de tiempo entre los dos sería milisegundos, no horas suponiendo que se encuentre en una zona horaria a horas de GMT. Como se indica a continuación, imprimir sus valores de cadena mostraría diferentes cadenas.

 25
Author: Carl Camera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-16 18:23:21

También tenga en cuenta la diferencia de rendimiento; DateTime.UtcNow es alrededor de 30 veces más rápido que DateTime.Ahora, porque internamente DateTime.Ahora está haciendo muchos ajustes de zona horaria (puede verificar esto fácilmente con Reflector).

Así que no uses DateTime.Ahora para mediciones de tiempo relativo.

 24
Author: Magnus Krisell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-21 13:16:17

Esta es una buena pregunta. Lo estoy reviviendo para dar un poco más de detalle sobre cómo se comporta. Net con diferentes valores 'Tipo'. Como señala @Jan Zich, en realidad es una propiedad críticamente importante y se establece de manera diferente dependiendo de si se usa Ahora o UtcNow.

Internamente la fecha se almacena como "Ticks" que (contrariamente a la respuesta de @Carl Camera) es diferente dependiendo de si usa Ahora o UtcNow.

DateTime.UtcNow se comporta como otros idiomas. Establece Ticks a un GMT valor basado. También establece 'Kind' a 'Utc'.

DateTime.Ahora altera el valor de las garrapatas a lo que sería si fuera su hora del día en la zona horaria GMT. También establece 'Tipo' a 'Local'.

Si tienes 6 horas de retraso (GMT-6), obtendrás la hora GMT de hace 6 horas. . Net en realidad ignora 'Amable' 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 crea una instancia de DateTime, luego cambia su zona horaria y intenta usarlo.

Las instancias DateTime con diferentes valores de tipo NO son compatibles.

Veamos algún 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. El Intervalo de tiempo debería haber sido de casi una hora, pero en cambio fue de casi 6. "utc

También puede ver el 'work around' que es simplemente convertir para el tiempo universal en cualquier lugar ese 'Tipo' no es lo mismo.

Mi respuesta directa a la pregunta concuerda con la recomendación de la respuesta aceptada sobre cuándo usar cada una. Siempre debe intentar trabajar con objetos DateTime que tengan Kind=Utc, excepto durante e/s (visualización y análisis). Esto significa que casi siempre debería usar DateTime.UtcNow, excepto en los casos en los que está creando el objeto solo para mostrarlo y descartarlo de inmediato.

 13
Author: Ted Bigham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-20 17:49:06

DateTime no tiene idea de qué zonas horarias son. Siempre asume que estás en tu hora local. UtcNow solo significa "Restar mi zona horaria del tiempo".

Si desea utilizar fechas con reconocimiento de zona horaria, utilice DateTimeOffset, que representa una fecha/hora con una zona horaria. Tuve que aprender eso de la manera difícil.

 6
Author: Omer van Kloeten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-15 11:05:41

Solo una pequeña adición a los puntos anteriores: la estructura DateTime también contiene un campo poco conocido llamado Kind (al menos, no lo sabía durante mucho tiempo). Es básicamente 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ó el estuco, también influye en la forma en que los métodos ToUniversalTime () y ToLocalTime () funciona.

 4
Author: Jan Zich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-18 00:12:29

La respuesta" simple " a la pregunta es:

DateTime.Ahora devuelve un valor DateTime que representa la hora actual del sistema (en cualquier zona horaria en la que se esté ejecutando el sistema). El DateTime.La propiedad Kind será DateTimeKind.Local

DateTime.UtcNow devuelve un valor DateTime que representa la Hora Universal Coordinada actual (también conocida como UTC) que será la misma independientemente de la zona horaria del sistema. El DateTime.La propiedad Kind será DateTimeKind.Utc

 4
Author: PapillonUK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-14 15:43:17
 2
Author: Sorin Comanescu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-15 13:11:06

DateTime.UtcNow es una escala de tiempo continua, de un solo valor, mientras que DateTime.Ahora no es continuo o de un solo valor. La razón principal es el horario de verano, que no se aplica a UTC. Así UTC nunca salta hacia adelante o hacia atrás una hora, mientras que la hora local (DateTime.Ahora) lo hace. Y cuando salta hacia atrás, el mismo valor de tiempo ocurre dos veces.

 1
Author: user1315023,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-08 13:49:53

DateTime.UtcNow es una escala de tiempo Universal que omite el Horario de verano. Así que UTC nunca cambia debido al horario de verano.

Pero, DateTime.Ahora no es continuo o de un solo valor porque cambia según el horario de verano. Lo que significa DateTime.Ahora, el mismo valor de tiempo puede ocurrir dos veces dejando a los clientes en un estado confuso.

 1
Author: ChaiVan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-03 10:31:28

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 cuestión de sus preferencias - probablemente hacer un sitio web local / aplicación independiente que desea utilizar el tiempo que el usuario tiene-tan afectado por su configuración de zona horaria - DateTime.Ahora.

Solo recuerde, para un sitio web es la configuración de zona horaria del servidor. Por lo tanto, si está mostrando la hora para el usuario, obtenga su zona horaria preferida y cambie la hora (simplemente guarde la hora Utc en la base de datos y modifíquela) o especifique su UTC. Si se olvida de hacerlo, el usuario puede ver algo como: publicado hace 3 menos y luego un momento en el futuro cerca de él:)

 0
Author: kender,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-15 11:04:40