2008-09-15 10 views
160

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

+1

puede ser demasiado tarde, pero quiero apuntar a este blog: http://blog.angeloflogic.com/2013/10/nlog-timestamps-with-millisecond.html –

+0

pequeña marca de banco http: // rextester. com/QRDR82396 –

Respuesta

260

DateTime.UtcNow le indica la fecha y la hora como en el Tiempo Universal Coordinado, que también se conoce como la zona horaria del meridiano de Greenwich, básicamente como si estuviese en Londres Inglaterra, pero no durante el verano. DateTime.Now le da la fecha y la hora como aparecería a alguien en su configuración regional actual.

Recomendaría usar DateTime.Now cada vez que se muestra una fecha para 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 desee almacenar fechas o usarlas para cálculos posteriores de esa manera (en un modelo de cliente-servidor) sus clientes no confunden sus cálculos en los husos horarios de su servidor o entre ellos.

+63

un excelente punto: cuando * almacena * fechas en una base de datos o archivo, ¡definitivamente guárdelas en UTC! –

+10

Debe tener en cuenta que cuando desea almacenar fechas en UTC en la base de datos, debe asegurarse de que la base de datos no agregue su propia zona horaria a las fechas que no proporcionan zonas horarias explícitas. Tenga en cuenta que DateTime siempre usará la zona horaria actual cuando se le solicite. –

+0

@OmervanKloeten da un muy buen punto. Me pregunto si hay una solución elegante y completa para esto, para almacenar y recibir las fechas correctamente todas las veces, incluso si su servidor IIS y SQL están en diferentes zonas horarias. – TheGeekZn

71

En realidad es muy sencillo, así que creo que depende de lo que su público es y dónde viven.

Si no usar UTC, que debe conocer la zona horaria de la persona que está mostrando las fechas y horas a - de lo contrario se les dirá algo ocurrió a las 3 pm en el sistema o servidor de tiempo, cuando se realmente sucedió a las 5 PM donde viven.

Utilizamos DateTime.UtcNow porque tenemos una audiencia de la web mundial, y porque yo prefiero no darle la lata a todos los usuarios a rellenar un formulario indicando qué zona horaria en que viven.

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

+0

I También quiero recordar que el almacenamiento de DateTime.UtcNow también solo es necesario cuando se realizan cálculos con 2 fechas para obtener las horas correctas. Cuando solo tengo que mostrar una fecha de registro, entonces Datetime.Now es suficiente. – Elisabeth

1

Cuando se necesita una hora local para la máquina de la aplicación se ejecuta en (CEST como para Europa), utilizar ahora. Si quieres un tiempo universal, UtcNow. Es solo cuestión de tus preferencias, probablemente crear un sitio web local o una aplicación independiente que quieras utilizar en función del tiempo que el usuario tenga, tan afectado por su configuración de zona horaria, DateTime.Now.

Solo recuerde, para un sitio web es la configuración de la zona horaria del servidor. Por lo tanto, si muestra 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 que es UTC. Si lo olvida, el usuario puede ver algo como: publicado hace 3 minutos y luego un momento en el futuro cerca de él :)

6

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

Si desea utilizar las fechas de zona horaria consciente, utilice DateTimeOffset, lo que representa una fecha/hora con una zona horaria. Tuve que aprenderlo de la manera difícil.

+7

Para ser completamente preciso (y evitar que las personas usen Now over UtcNow por razones de rendimiento), es al revés: ahora agrega la zona horaria a UtcNow y, de hecho, es una magnitud más lenta. – mafu

24

Un concepto principal de entender en .NET es que ahora es ahora por toda la tierra, no importa qué zona horaria está en Así que si se carga una variable con DateTime.Now o DateTime.UtcNow. - la asignación es idéntica. * Su 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 cuando se calculan las 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 quiere determinar correctamente el número de horas del tiempo A y el tiempo B, primero debe traducir cada una a sus equivalentes UTC antes de calcular el TimeSpan.

Esto está cubierto por una blog post i wrote que explica además TimeSpan, e incluye un enlace a una aún más extenso artículo MS 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 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.

+1

Con respecto a "cargar una variable con DateTime.Now o DateTime".? UtcNow - la asignación es idéntico ": Esto puede ser necesario aclarar Mientras estoy aquí sentado en la zona horaria local (UTC -4), que asigna a dos variables DateTime.UtcNow y DateTime.Now respectivamente, y luego impresa con sus valores ToString() los valores mostrados fueron 4 horas de diferencia - no "idéntico". –

+2

@JonSchneider, creo que estás en lo correcto, la sentencia:.. "la asignación es idéntica" no es cierto ToString() no es probablemente la mejor manera. para probar que, debido a que podría * * visualización fechas iguales de manera diferente (como Java hace) Las funciones de comparación son una prueba mejor, y demostrar que de hecho no son iguales –

+0

Aclaración a mi declaración "idéntico":.. de carga a través de una variable DateTime.Now y otro con DateTime.UtcNow y luego imprimir la diferencia TimeSpan. la diferencia será milisegundos y no horas Suponiendo que está lejos de horas GMT. –

21

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

Así que no use DateTime.Now para mediciones de tiempo relativo.

4

Solo una pequeña adición a los puntos mencionados anteriormente: la estructura DateTime también contiene un campo poco conocido llamado Kind (al menos, no lo conocía desde hace mucho tiempo). Básicamente es solo una bandera que indica si la hora es local o UTC; no especifica la compensación real de UTC para las horas locales. Además del hecho de que indica con qué intenciones se construyó el conducto, también influye en la forma en que funcionan los métodos ToUniversalTime() y ToLocalTime().

2

La respuesta "simple" a la pregunta es:

DateTime.Now devuelve un valorDateTime que representa la, hora actual del sistema (en lo cada vez que se ejecuta el sistema en la zona horaria). La propiedad DateTime.Kind será DateTimeKind.Local

DateTime.UtcNow devuelve un valorDateTime que representa la corriente Tiempo Universal Coordinado (UTC aka) que será el mismo, independientemente del sistema de zona horaria. El DateTime.Kind propiedad será DateTimeKind.Utc

1

DateTime.UtcNow es una escala continua, de un solo valor de tiempo, mientras que DateTime.Now no es continua o de un solo valor. La razón principal es el horario de verano, que no se aplica a UTC. Así que UTC nunca salta hacia delante o hacia atrás 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.

12

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

Internamente la fecha se almacena como "Ticks" que (al contrario 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' en 'Utc'.

DateTime.Now altera el valor de Ticks a lo que sería si fuera tu hora del día en la zona horaria GMT. También establece 'Tipo' 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, aunque se supone que es "ahora". Esto se rompe aún más si crea una instancia de DateTime, luego cambia su zona horaria e intenta usarla.

Las instancias de DateTime con diferentes valores 'Kind' NO son compatibles. mirada

Vamos en 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 se puede ver aquí, comparaciones y funciones matemáticas no se convierten automáticamente en horarios compatibles. El Timespan debería haber sido de casi una hora, pero en su lugar era casi 6. "utc < ahora" debería haber sido cierto (incluso agregué una hora para estar seguro), pero seguía siendo falso.

También puede ver el 'trabajo alrededor' que es simplemente convertir a la hora universal en cualquier lugar que 'Kind' no sea el mismo.

Mi respuesta directa a la pregunta concuerda con la recomendación de la respuesta aceptada sobre cuándo usar cada una. Debería siempre probar para trabajar con objetos DateTime que tienen Kind = Utc, excepto durante i/o (visualización y análisis). Esto significa que casi siempre debe utilizar DateTime.UtcNow, excepto en los casos en los que crea el objeto solo para mostrarlo, y descartarlo de inmediato.

Cuestiones relacionadas