Pregunta

¿Cómo funciona la conversión a UTC del formato DateTime estándar?

Más específicamente, si creo un objeto DateTime en una zona horaria y luego cambio a otra zona horaria y ejecuto ToUniversalTime () , ¿cómo sabe esto? ¿La conversión se realizó correctamente y el tiempo aún está representado con precisión?

¿Fue útil?

Solución

No hay una zona horaria implícita adjunta a un objeto DateTime . Si ejecuta ToUniversalTime () en él, usa la zona horaria del contexto en el que se está ejecutando el código.

Por ejemplo, si creo un DateTime de la época del 1/1/1970, me da el mismo objeto DateTime sin importar en qué parte del mundo estoy .

Si ejecuto ToUniversalTime () en él cuando ejecuto el código en Greenwich, obtengo el mismo tiempo. Si lo hago mientras vivo en Vancouver, obtengo un objeto de DateTime de -8 horas.

Es por esto que es importante almacenar información relacionada con el tiempo en su base de datos como UTC cuando necesita realizar cualquier tipo de conversión o localización de fecha. Considere si su base de código se movió a una instalación de servidor en otra zona horaria;)

Editar: nota de la respuesta de Joel: los objetos DateTime por defecto se escriben como DateTimeKind.Local . Si analiza una fecha y la establece como DateTimeKind.Utc , entonces ToUniversalTime () no realiza ninguna conversión.

Y aquí hay un artículo en " Mejores prácticas de codificación con fecha y hora " , y un artículo en Conversión de tiempos de fecha con .Net .

Otros consejos

En primer lugar, comprueba si el Tipo de DateTime ya se conoce como UTC. Si es así, devuelve el mismo valor.

De lo contrario, se supone que es una hora local, que es local para la computadora en la que se está ejecutando, y en particular en la zona horaria que la computadora estaba usando cuando alguna propiedad privada se inicializó por primera vez con pereza. Eso significa que si cambia la zona horaria después de que se inició su aplicación, existe una gran posibilidad de que aún esté usando la anterior.

La zona horaria contiene suficiente información para convertir una hora local a una hora UTC o viceversa, aunque hay veces que es ambiguo o no válido. (Hay horarios locales que ocurren dos veces, y horarios locales que nunca ocurren debido al horario de verano). Las reglas para manejar estos casos se especifican en la documentación :

  

Si el valor de la instancia de fecha y hora es   Un tiempo ambiguo, asume este método.   Que es un tiempo estándar. (Un   El tiempo ambiguo es uno que puede mapear   ya sea a una hora estándar o a una   Horario de verano en la hora local.   zona) Si la fecha y hora instancia   valor es un tiempo inválido, este método   simplemente resta la hora local de   el desplazamiento UTC de la zona horaria local a   Vuelve UTC. (Un tiempo inválido es uno   que no existe debido a la   Aplicación del horario de verano.   reglas de ajuste.)

El valor devuelto tendrá un Tipo de DateTimeKind.Utc , por lo que si llama ToUniveralTime no aplicará el desplazamiento otra vez. (¡Esta es una gran mejora sobre .NET 1.1!)

Si desea una zona horaria no local, debe usar < código> TimeZoneInfo que se introdujo en .NET 3.5 (existen soluciones piratas para versiones anteriores, pero no son agradables). Para representar un instante en el tiempo, debe considerar el uso de DateTimeOffset que se introdujo en .NET 2.0SP1, .NET3.0SP1 y .NET 3.5. Sin embargo, eso todavía no tiene una zona horaria real asociada, solo un desplazamiento de UTC. Eso significa que no sabe qué hora local será una hora más tarde, por ejemplo, las reglas de horario de verano pueden variar entre las zonas horarias que usaron el mismo desplazamiento para ese instante en particular. TimeZoneInfo está diseñado para tener en cuenta las reglas históricas y futuras, a diferencia de TimeZone que es algo simplista.

Básicamente, el soporte en .NET 3.5 es mucho mejor de lo que era, pero aún deja mucho que desear para la aritmética de calendario adecuada. ¿Alguien desea trasladar Joda Time a .NET? ;)

Lo que @womp dijo , con la adición de que verifica la propiedad DateTime's Kind para ver si podría ya será una fecha UTC.

DateTime.ToUniversalTime elimina el desplazamiento de la zona horaria de la zona horaria local para normalizar DateTime a UTC. Si luego usa DateTime.ToLocalTime en el valor normalizado en otra zona horaria, el desplazamiento de la zona horaria de esa zona horaria se agregará al valor normalizado para la representación correcta en esa zona horaria.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top