Horario de verano y mejores prácticas de zona horaria [cerrado]


2047

Espero hacer esta pregunta y sus respuestas como la guía definitiva para lidiar con el horario de verano, en particular para lidiar con los cambios reales.

Si tiene algo que agregar, por favor hágalo

Muchos sistemas dependen de mantener la hora exacta, el problema es con los cambios en el horario debido al horario de verano: mover el reloj hacia adelante o hacia atrás.

Por ejemplo, uno tiene reglas comerciales en un sistema de toma de pedidos que dependen de la hora del pedido; si el reloj cambia, las reglas pueden no ser tan claras. ¿Cómo debe persistir el tiempo de la orden? Por supuesto, hay una infinidad de escenarios: este es simplemente ilustrativo.

  • ¿Cómo ha solucionado el problema del horario de verano?
  • ¿Qué supuestos son parte de su solución? (buscando contexto aquí)

Tan importante, si no más:

  • ¿Qué intentaste que no funcionó?
  • ¿Por qué no funcionó?

Me interesaría la programación, el sistema operativo, la persistencia de datos y otros aspectos pertinentes del problema.

Las respuestas generales son geniales, pero también me gustaría ver detalles, especialmente si solo están disponibles en una plataforma.


2
@abatishchev: esta forma GETDATE()en SQL será UTC (como lo hará DateTime.Now). Y el servidor no se verá afectado por ningún tipo de cambio automático de horario de verano.
Finalizado

44
@Oded: puedo aceptar si se agregará "en el servidor". Pero aún así eso puede afectar a otras aplicaciones que necesitan hora local. Por esta y otras razones, creo que es mejor solicitar el tiempo Utc explícitamente.
abatishchev 01 de

77
Se prefiere UTC a GMT, tanto porque está definido con mayor precisión como porque las definiciones de GMT están en mal estado en algunos sistemas operativos. Es común que las personas traten los términos "GMT" y "UTC" como intercambiables, pero no lo son por completo. Para casi cualquier propósito de software / sistema, use UTC. Ver stackoverflow.com/questions/2292334/…
Chris Johnson

77
@JoshStodola - La ' respuesta ' de Jon Skeet .
Kenny Evitt

1
@De acuerdo, no puede asumir que el servidor estará en UTC, he visto servidores de producción en los que la zona horaria era "UTC" pero había aplicado DST, por lo que en realidad era UTC + 1 durante más de la mitad del año. De acuerdo con @abatishchev ser explícito y el uso DateTime.UtcNowy GETUTCDATE(), también muestra otros desarrolladores que realmente has pensado en ello
ono2012

Respuestas:


940

Resumen de respuestas y otros datos: (agregue los suyos)

Hacer:

  • Siempre que se refiera a un momento exacto en el tiempo, persista el tiempo de acuerdo con un estándar unificado que no se vea afectado por el horario de verano. (GMT y UTC son equivalentes a este respecto, pero se prefiere usar el término UTC. Tenga en cuenta que UTC también se conoce como hora Zulu o Z ).
  • Si, en cambio, elige persistir una hora utilizando un valor de hora local, incluya la compensación de hora local para esta hora en particular desde UTC (esta compensación puede cambiar durante todo el año), de modo que la marca de tiempo se pueda interpretar sin ambigüedades.
  • En algunos casos, es posible que deba almacenar tanto la hora UTC como la hora local equivalente. A menudo, esto se hace con dos campos separados, pero algunas plataformas admiten un datetimeoffsettipo que puede almacenar ambos en un solo campo.
  • Al almacenar marcas de tiempo como un valor numérico, use el tiempo Unix , que es el número de segundos completos desde entonces 1970-01-01T00:00:00Z(excluyendo los segundos bisiestos). Si necesita mayor precisión, use milisegundos en su lugar. Este valor siempre debe basarse en UTC, sin ningún ajuste de zona horaria.
  • Si más tarde necesita modificar la marca de tiempo, incluya la ID de zona horaria original para que pueda determinar si el desplazamiento puede haber cambiado desde el valor original registrado.
  • Al programar eventos futuros, generalmente se prefiere la hora local en lugar de UTC, ya que es común que cambie la compensación. Ver respuesta y publicación de blog .
  • Al almacenar fechas completas, como cumpleaños y aniversarios, no convierta a UTC ni a ninguna otra zona horaria.
    • Cuando sea posible, almacene en un tipo de datos de solo fecha que no incluya una hora del día.
    • Si dicho tipo no está disponible, asegúrese de ignorar siempre la hora del día al interpretar el valor. Si no puede estar seguro de que se ignorará la hora del día, elija 12:00 mediodía en lugar de 00:00 medianoche como un horario representativo más seguro ese día.
  • Recuerde que las compensaciones de zona horaria no siempre son un número entero de horas (por ejemplo, la hora estándar de la India es UTC + 05: 30, y Nepal usa UTC + 05: 45).
  • Si usa Java, use java.time para Java 8 y versiones posteriores.
  • Si usa .NET , considere usar Noda Time .
  • Si usa .NET sin Noda Time, considere que a DateTimeOffsetmenudo es una mejor opción que DateTime.
  • Si usa Perl, use DateTime .
  • Si usa Python, use pytz o dateutil .
  • Si usa JavaScript, use moment.js con la extensión moment-timezone .
  • Si usa PHP> 5.2, use las conversiones de zonas horarias nativas proporcionadas por DateTimey DateTimeZoneclases. Tenga cuidado al usar DateTimeZone::listAbbreviations()- vea la respuesta . Para mantener PHP con datos actualizados de Olson, instale periódicamente el paquete timezonedb PECL; véase la respuesta .
  • Si usa C ++, asegúrese de usar una biblioteca que implemente correctamente la base de datos de zona horaria de IANA . Estos incluyen cctz , ICU y la biblioteca "tz" de Howard Hinnant .
    • No use Boost para conversiones de zona horaria. Si bien su API afirma ser compatible con los identificadores estándar de IANA (también conocidos como "zoneinfo"), los mapea crudamente con datos de estilo POSIX, sin considerar el rico historial de cambios que puede haber tenido cada zona. (Además, el archivo se ha quedado sin mantenimiento).
  • Si usa Rust, use crono .
  • La mayoría de las reglas comerciales utilizan el tiempo civil, en lugar de UTC o GMT. Por lo tanto, planifique convertir las marcas de tiempo UTC a una zona horaria local antes de aplicar la lógica de la aplicación.
  • Recuerde que las zonas horarias y las compensaciones no son fijas y pueden cambiar. Por ejemplo, históricamente EE. UU. Y el Reino Unido utilizaron las mismas fechas para 'avanzar' y 'retroceder'. Sin embargo, en 2007, EE. UU. Cambió las fechas de cambio de los relojes. Esto ahora significa que durante 48 semanas del año la diferencia entre el horario de Londres y el horario de Nueva York es de 5 horas y durante 4 semanas (3 en la primavera, 1 en el otoño) es de 4 horas. Tenga en cuenta elementos como este en cualquier cálculo que involucre múltiples zonas.
  • Considere el tipo de tiempo (tiempo real del evento, tiempo de transmisión, tiempo relativo, tiempo histórico, tiempo recurrente) qué elementos (marca de tiempo, desplazamiento de zona horaria y nombre de zona horaria) necesita almacenar para una recuperación correcta; consulte "Tipos de tiempo" en esta respuesta .
  • Mantenga sincronizados los archivos tzdata de su sistema operativo, base de datos y aplicaciones, entre ellos y el resto del mundo.
  • En los servidores, configure los relojes de hardware y de SO en UTC en lugar de en una zona horaria local.
  • Independientemente del punto anterior, el código del lado del servidor, incluidos los sitios web, nunca debe esperar que la zona horaria local del servidor sea algo en particular. véase la respuesta .
  • Prefiere trabajar con zonas horarias caso por caso en el código de su aplicación, en lugar de hacerlo globalmente a través de la configuración del archivo de configuración o los valores predeterminados.
  • Use los servicios NTP en todos los servidores.
  • Si usa FAT32 , recuerde que las marcas de tiempo se almacenan en la hora local, no en UTC.
  • Cuando se trata de eventos recurrentes (programa de televisión semanal, por ejemplo), recuerde que la hora cambia con el horario de verano y será diferente según las zonas horarias.
  • Siempre consulte los valores de fecha y hora como inclusivo de límite inferior, exclusivo de límite superior ( >=, <).

No:

  • No confunda una "zona horaria", como America/New_Yorkcon un "desplazamiento de zona horaria", como -05:00. Son dos cosas diferentes. Vea el wiki de etiqueta de zona horaria .
  • No utilice el Dateobjeto de JavaScript para realizar cálculos de fecha y hora en navegadores web más antiguos, ya que ECMAScript 5.1 y versiones anteriores tienen un defecto de diseño que puede utilizar incorrectamente el horario de verano. (Esto se solucionó en ECMAScript 6/2015).
  • Nunca confíes en el reloj del cliente. Puede muy bien ser incorrecto.
  • No le digas a la gente que "siempre use UTC en todas partes". Este consejo generalizado es miope de varios escenarios válidos que se describen anteriormente en este documento. En su lugar, use la referencia de tiempo apropiada para los datos con los que está trabajando. (La marca de tiempo puede usar UTC, pero la programación de tiempos futuros y los valores de solo fecha no deberían).

Pruebas:

  • Al realizar la prueba, asegúrese de evaluar países en los hemisferios occidental, oriental, norte y sur (de hecho, en cada cuarto del mundo, es decir, 4 regiones), con DST en progreso y no (da 8), y un país que sí no use DST (otras 4 para cubrir todas las regiones, haciendo 12 en total).
  • Pruebe la transición del horario de verano, es decir, cuando se encuentra actualmente en verano, seleccione un valor de tiempo en invierno.
  • Pruebe casos límite, como una zona horaria que sea UTC + 12, con DST, haciendo que la hora local sea UTC + 13 en verano e incluso lugares que sean UTC + 13 en invierno
  • Pruebe todas las bibliotecas y aplicaciones de terceros y asegúrese de que manejen los datos de zona horaria correctamente.
  • Pruebe zonas horarias de media hora, al menos.

Referencia:

Otro:

  • Presiona a tu representante para que termine la abominación que es el horario de verano. Siempre podemos esperar ...
  • Lobby para la hora estándar de la Tierra

31
El uso de GMT realmente no resuelve el problema, aún necesita averiguar cuál es el delta correcto para aplicar, y aquí es donde reside toda la complejidad. El delta puede ser complejo de determinar en sistemas que utilizan los usuarios en diferentes regiones (con diferentes horarios de cambio de horario de verano) o en sistemas que muestran datos históricos / futuros.
ckarras

10
Eso es cierto si todo lo que la aplicación necesita hacer es mostrar la hora local actual. Pero si tenemos, por ejemplo, un servidor en Australia que necesita mostrar la fecha / hora de una transacción en Canadá el 2 de abril de 2006 (este fue el último año antes de que las reglas de cambio de horario de verano cambiaran en Canadá), ¿tiene una llamada del sistema operativo? que puede hacer DateTime ("2006/04/02 14: 35Z"). ToLocalTime (). WithDaylightSavingRules ("Canada", 2006)?
ckarras

22
Sí, existe una llamada de SO en Windows: SystemTimeToTzSpecificLocation. msdn.microsoft.com/en-us/library/ms724949(VS.85).aspx
Michael Madsen el

77
@tchrist Quizás si eres persistente puedes.
Peter Ajtai

16
Tenga en cuenta que al convertir fechas futuras (incluso solo mañana) a UTC, siempre pierde algo. Por ejemplo, usó algún desplazamiento conocido para hacer esa conversión, pero dado que la fecha es futura, siempre existe la posibilidad de que el grupo que establece esas reglas cambie esas reglas. Además, es prácticamente imposible convertir algunas fechas futuras a UTC porque los horarios de verano no se conocen hasta ese año (algunos países establecen las fechas cada año, no más de 10 años por delante o en base a las reglas establecidas).
eselk

319

No estoy seguro de qué puedo agregar a las respuestas anteriores, pero aquí hay algunos puntos de mi parte:

Tipos de tiempos

Hay cuatro momentos diferentes que debe considerar:

  1. Hora del evento: por ejemplo, la hora en que ocurre un evento deportivo internacional, o una coronación / muerte / etc. Esto depende de la zona horaria del evento y no del espectador.
  2. Hora de televisión: por ejemplo, un programa de televisión en particular se transmite a las 9 p.m. hora local en todo el mundo. Importante al pensar en publicar los resultados (por ejemplo, American Idol) en su sitio web
  3. Tiempo relativo: por ejemplo: esta pregunta tiene una recompensa abierta que se cierra en 21 horas. Esto es fácil de mostrar
  4. Hora recurrente: por ejemplo: un programa de televisión está todos los lunes a las 9 p.m., incluso cuando cambia el horario de verano.

También hay tiempo histórico / alternativo. Estos son molestos porque es posible que no se correspondan con el tiempo estándar. Por ejemplo: fechas julianas, fechas según un calendario lunar en Saturno, el calendario klingon.

El almacenamiento de marcas de tiempo de inicio / finalización en UTC funciona bien. Para 1, necesita un nombre de zona horaria de evento + desplazamiento almacenado junto con el evento. Para 2, necesita un identificador de hora local almacenado con cada región y un nombre de zona horaria local + desplazamiento almacenado para cada espectador (es posible derivar esto de la IP si tiene problemas). Para 3, almacene en segundos UTC y no necesita zonas horarias. 4 es un caso especial de 1 o 2 dependiendo de si se trata de un evento global o local, pero también debe almacenar un creado en la marca de tiempo para que pueda saber si una definición de zona horaria cambió antes o después de que se creó este evento. Esto es necesario si necesita mostrar datos históricos.

Tiempos de almacenamiento

  • Siempre guarde el tiempo en UTC
  • Convertir a hora local en la pantalla (local definido por el usuario que mira los datos)
  • Al almacenar una zona horaria, necesita el nombre, la marca de tiempo y el desplazamiento. Esto es necesario porque los gobiernos a veces cambian el significado de sus zonas horarias (por ejemplo: el gobierno de EE. UU. Cambió las fechas del horario de verano), y su aplicación necesita manejar las cosas con gracia ... por ejemplo: la marca de tiempo exacta cuando los episodios de PERDIDO mostraron tanto antes como después de las reglas del horario de verano cambiado

Desplazamientos y nombres

Un ejemplo de lo anterior sería:

El juego de la final de la copa mundial de fútbol tuvo lugar en Sudáfrica (UTC + 2 - SAST) el 11 de julio de 2010 a las 19:00 UTC.

Con esta información, podemos determinar históricamente la hora exacta en que se llevaron a cabo las finales de la WCS 2010, incluso si la definición de la zona horaria de Sudáfrica cambia, y poder mostrar eso a los espectadores en su zona horaria local en el momento en que consultan la base de datos.

Hora del sistema

También debe mantener sincronizados los archivos tzdata de su sistema operativo, base de datos y aplicaciones, tanto entre sí como con el resto del mundo, y realizar pruebas exhaustivas cuando realice la actualización. No es extraño que una aplicación de terceros de la que depende no haya manejado un cambio de TZ correctamente.

Asegúrese de que los relojes de hardware estén configurados en UTC, y si está ejecutando servidores en todo el mundo, asegúrese de que sus sistemas operativos también estén configurados para usar UTC. Esto se hace evidente cuando necesita copiar archivos de registro apache rotados por hora desde servidores en varias zonas horarias. Ordenarlos por nombre de archivo solo funciona si todos los archivos se nombran con la misma zona horaria. También significa que no tienes que hacer cálculos matemáticos en la cabeza cuando pasas de una casilla a otra y necesitas comparar marcas de tiempo.

Además, ejecute ntpd en todos los cuadros.

Clientela

Nunca confíe en la marca de tiempo que obtiene de una máquina cliente como válida. Por ejemplo, la Fecha: encabezados HTTP o una Date.getTime()llamada de JavaScript . Estos están bien cuando se usan como identificadores opacos, o cuando se hacen cálculos de fechas durante una sola sesión en el mismo cliente, pero no intente hacer una referencia cruzada de estos valores con algo que tenga en el servidor. Sus clientes no ejecutan NTP, y pueden no tener necesariamente una batería que funcione para su reloj BIOS.

Trivialidades

Finalmente, los gobiernos a veces harán cosas muy raras:

El tiempo estándar en los Países Bajos fue exactamente 19 minutos y 32.13 segundos por delante de UTC por ley desde 1909-05-01 hasta 1937-06-30. Esta zona horaria no se puede representar exactamente con el formato HH: MM.

Ok, creo que he terminado.


66
Esta respuesta tiene algunos puntos geniales, especialmente quería señalar esta parte "Tiempo recurrente: por ejemplo: un programa de televisión es todos los lunes a las 9 p.m., incluso cuando cambia el horario de verano". muchos de los aspectos difíciles de lidiar con zonas horarias. Sin embargo, manejar "eventos recurrentes" que cruzan las barreras del horario de verano se vuelve mucho más difícil.
Jared Hales

45
+1 para las curiosidades. Mantener el contenido interesante hace que esta tarea sea más agradable, lo que puede conducir a una mayor productividad :)
Chris

44
Hay muchas cosas buenas en esta respuesta, pero algunos problemas. 1) Muchas abreviaturas de zona horaria son ambiguas. ver aquí 2) No siempre quieres almacenar en UTC. La mayoría de las veces, sí, pero el contexto importa. En sus términos, el tiempo de televisión no se almacenaría en UTC. Además, a veces es ilegal o contrario a la política no almacenar la hora local, que es donde cosas como DateTimeOffset(o equivalentes) son útiles. De lo contrario, buena redacción.
Matt Johnson-Pint el

1
Por lo tanto, todos están de acuerdo en que la biblioteca Joda es, con mucho, la mejor herramienta disponible para el trabajo. Sin embargo, debemos seguir actualizando (reconstruyendo) el archivo jar JODA según este artículo ( joda.org/joda-time/tz_update.html ) para mantenernos actualizados con la última información de zona horaria. ¿Hay alguna forma estándar de descargar los últimos datos de zona horaria del sitio web de IANA ( iana.org/time-zones ) y reconstruir la biblioteca joda? En otras palabras, ¿es posible automatizar este proceso en lugar de hacerlo manualmente?
saravana_pc

2
La curiosidad de los Países Bajos parece legítima. ietf.org/rfc/rfc3339.txt sección 5.8. A mitad de camino pensé que alguien estaba tirando de nuestra pierna.
ruffin

89

Este es un tema importante y sorprendentemente difícil. La verdad es que no existe un estándar completamente satisfactorio para el tiempo persistente. Por ejemplo, el estándar SQL y el formato ISO (ISO 8601) claramente no son suficientes.

Desde el punto de vista conceptual, generalmente se tratan dos tipos de datos de fecha y hora, y es conveniente distinguirlos (los estándares anteriores no lo hacen): " tiempo físico " y " tiempo civil ".

Un instante de tiempo "físico" es un punto en la línea de tiempo universal continua que la física trata (ignorando la relatividad, por supuesto). Este concepto puede codificarse adecuadamente en UTC, por ejemplo (si puede ignorar los segundos bisiestos).

Un tiempo "civil" es una especificación de fecha y hora que sigue las normas civiles: un punto de tiempo aquí está completamente especificado por un conjunto de campos de fecha y hora (Y, M, D, H, MM, S, FS) más un TZ (especificación de zona horaria) (también un "calendario", en realidad; pero supongamos que restringimos la discusión al calendario gregoriano). Una zona horaria y un calendario permiten conjuntamente (en principio) mapear de una representación a otra. Pero los instantes de tiempo civil y físico son fundamentalmente diferentes tipos de magnitudes, y deben mantenerse conceptualmente separados y tratados de manera diferente (una analogía: conjuntos de bytes y cadenas de caracteres).

El tema es confuso porque hablamos de estos tipos de eventos indistintamente y porque los tiempos civiles están sujetos a cambios políticos. El problema (y la necesidad de distinguir estos conceptos) se vuelve más evidente para los eventos en el futuro. Ejemplo (tomado de mi discusión aquí .

John registra en su calendario un recordatorio para algún evento en fecha 2019-Jul-27, 10:30:00y hora , TZ = Chile/Santiago, (que ha compensado GMT-4, por lo tanto, corresponde a UTC 2019-Jul-27 14:30:00). Pero algún día en el futuro, el país decide cambiar la compensación de TZ a GMT-5.

Ahora, cuando llegue el día ... si ese recordatorio se dispara a

A) 2019-Jul-27 10:30:00 Chile/Santiago = UTC time 2019-Jul-27 15:30:00?

o

B) 2019-Jul-27 9:30:00 Chile/Santiago = UTC time 2019-Jul-27 14:30:00?

No hay una respuesta correcta, a menos que uno sepa a qué se refería John conceptualmente cuando le dijo al calendario "Por favor, llámame 2019-Jul-27, 10:30:00 TZ=Chile/Santiago".

¿Se refería a una "fecha-hora civil" ("cuando los relojes de mi ciudad dan las 10:30")? En ese caso, A) es la respuesta correcta.

¿O quiso decir un "instante físico del tiempo", un punto en la línea continua de tiempo de nuestro universo, por ejemplo, "cuando ocurra el próximo eclipse solar". En ese caso, la respuesta B) es la correcta.

Algunas API de fecha / hora hacen esta distinción correcta: entre ellas, Jodatime , que es la base de la próxima (¡tercera!) API Java DateTime (JSR 310).


1
Otro punto a considerar que no he visto abordado en las API es que, incluso cuando se dan la hora y la zona horaria, hay al menos dos significados posibles para, por ejemplo, "13: 00: 00EDT". Podría referirse a algo que se sabe que ocurrió a la 1 p.m. hora local, que se creía que era la hora de verano del este, o algo que se sabe que ocurrió en el momento en que la hora del este llegó a las 13:00, que se cree que han ocurrido en un lugar observando el horario de verano del este. Si uno tiene muchas marcas de tiempo en que la información de zona horaria puede ser incorrecto (por ejemplo, archivos de cámaras digitales) ...
supercat

1
... saber si reflejan una hora local precisa o una hora global puede ser importante para determinar cómo corregirlos.
supercat

3
Claramente, John quiere A) porque la gente va a trabajar a las 8:30, cualquiera que sea el horario de verano o la zona horaria actual. Si entran a DST, irán a trabajar a las 8:30, cuando salgan de DST, irán a trabajar a las 8:30. Si el país decide mudarse a otra zona horaria, irán a trabajar a las 8:30 todos los días
Gianluca Ghettini

59

Haga una clara separación arquitectónica de las preocupaciones: para saber exactamente qué nivel interactúa con los usuarios y tiene que cambiar la fecha y hora para / desde la representación canónica (UTC). La fecha y hora no UTC es la presentación (sigue a la zona horaria local de los usuarios), la hora UTC es el modelo (sigue siendo única para los niveles intermedios y de fondo).

Además, decida cuál es su audiencia real, a qué no tiene que servir y dónde traza la línea . No toque calendarios exóticos a menos que realmente tenga clientes importantes allí y luego considere servidores separados orientados al usuario solo para esa región.

Si puede adquirir y mantener la ubicación del usuario, use la ubicación para la conversión sistemática de fecha y hora (por ejemplo, cultura .NET o una tabla SQL), pero proporcione una forma para que el usuario final elija anulaciones si la fecha y hora es crítica para sus usuarios.

Si hay obligaciones de auditoría histórica involucradas (como decir exactamente cuándo Jo en AZ pagó una factura hace 2 años en septiembre), entonces mantenga tanto la hora UTC como la hora local para el registro (sus tablas de conversión cambiarán con el tiempo).

Defina el huso horario referencial de tiempo para los datos que vienen en forma masiva , como archivos, servicios web, etc. Digamos que la compañía de la Costa Este tiene un centro de datos en CA: debe preguntar y saber qué usan como estándar en lugar de asumir uno u otro.

No confíe en las compensaciones de zona horaria incrustadas en la representación textual de la fecha y hora y no acepte analizarlas y seguirlas. En su lugar, solicite siempre que la zona horaria y / o la zona de referencia tengan que definirse explícitamente . Puede recibir fácilmente el tiempo con desplazamiento PST, pero el tiempo es en realidad EST ya que es el tiempo de referencia del cliente y los registros se exportaron a un servidor que está en PST.


40

Debe conocer la base de datos Olson tz , que está disponible en ftp://elsie.nci.nih.gov/pub http://iana.org/time-zones/ . Se actualiza varias veces al año para hacer frente a los cambios a menudo de última hora en cuándo (y si) cambiar entre el invierno y el verano (horario estándar y horario de verano) en diferentes países del mundo. En 2009, el último lanzamiento fue 2009; en 2010, fue 2010n; en 2011, fue 2011n; a finales de mayo de 2012, el lanzamiento fue 2012c. Tenga en cuenta que hay un conjunto de códigos para administrar los datos y los datos de la zona horaria en sí, en dos archivos separados (tzcode20xxy.tar.gz y tzdata20xxy.tar.gz). Tanto el código como los datos son de dominio público.

Esta es la fuente de nombres de zonas horarias como América / Los_Angeles (y sinónimos como Estados Unidos / Pacífico).

Si necesita realizar un seguimiento de diferentes zonas, entonces necesita la base de datos Olson. Como otros han aconsejado, también desea almacenar los datos en un formato fijo (UTC es normalmente el elegido) junto con un registro de la zona horaria en la que se generaron los datos. Es posible que desee distinguir entre el desplazamiento de UTC en el momento y el nombre de la zona horaria; eso puede hacer la diferencia más tarde. Además, sabiendo que actualmente es 2010-03-28T23: 47: 00-07: 00 (EE. UU. / Pacífico) puede o no ayudarlo a interpretar el valor 2010-11-15T12: 30, que presumiblemente se especifica en PST ( Hora estándar del Pacífico) en lugar de PDT (hora de verano del Pacífico).

Las interfaces estándar de la biblioteca C no son terriblemente útiles con este tipo de cosas.


Los datos de Olson se han movido, en parte porque AD Olson se retirará pronto, y en parte porque hubo una demanda (ahora desestimada) contra los mantenedores por infracción de derechos de autor. La base de datos de zonas horarias ahora se administra bajo los auspicios de IANA , la Autoridad de Números Asignados de Internet, y hay un enlace en la página principal a 'Base de datos de zonas horarias' . La lista de correo de discusión es ahora tz@iana.org; La lista de anuncios es tz-announce@iana.org.


12
La base de datos Olson también contiene datos históricos , lo que la hace particularmente útil para manejar el horario de verano. Por ejemplo, sabe que un valor UTC correspondiente al 31 de marzo de 2000 en los EE. UU. No está en DST, pero un valor UTC correspondiente al 31 de marzo de 2008 en los EE. UU. Sí.
Josh Kelley

3
El Consorcio Unicode mantiene un mapeo entre los identificadores de zona de Tomo de Olson y los identificadores de zona horaria de Windows: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/…
Josh Kelley

Enlace actualizado para la página del Consorcio Unicode: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/…
Span

¿Dónde se puede encontrar información sobre el análisis de los archivos Olson? Quiero compilarlo en una tabla db, pero no puedo averiguar cómo debería leer los archivos
Salatiel

@gidireich: la información principal se encuentra con los datos, y no es fácil de entender. La documentación principal está en la zic.8página del manual (o zic.8.txt). Necesitará el tzcode2011i.tar.gzarchivo en lugar de, o también, el tzdata2011i.tar.gzarchivo para obtener esta información.
Jonathan Leffler

26

En general, incluya el desplazamiento de hora local (incluido el desplazamiento de DST) en las marcas de tiempo almacenadas: UTC por sí solo no es suficiente si luego desea mostrar la marca de tiempo en su zona horaria original (y la configuración de DST).

Tenga en cuenta que el desplazamiento no siempre es un número entero de horas (por ejemplo, la hora estándar de la India es UTC + 05: 30).

Por ejemplo, los formatos adecuados son una tupla (tiempo unix, desplazamiento en minutos) o ISO 8601 .


55
Para la visualización, el desplazamiento es perfecto. Si desea realizar cambios, el desplazamiento aún no es suficiente. También debe conocer la zona horaria porque el nuevo valor puede requerir un desplazamiento diferente.
Matt Johnson-Pint el

23

Cruzar la frontera del "tiempo de la computadora" y el "tiempo de la gente" es una pesadilla. La principal es que no hay ningún tipo de estándar para las reglas que rigen las zonas horarias y los horarios de verano. Los países son libres de cambiar sus reglas de zona horaria y horario de verano en cualquier momento, y lo hacen.

Algunos países, como Israel, Brasil, deciden cada año cuándo tener su horario de verano, por lo que es imposible saber de antemano cuándo (si) estará vigente el horario de verano. Otros tienen reglas fijas (ish) sobre cuándo está vigente el horario de verano. Otros países no usan DST como todos.

Las zonas horarias no tienen que ser diferencias de hora completa de GMT. Nepal es +5.45. Incluso hay zonas horarias que son +13. Eso significa que:

SUN 23:00 in Howland Island (-12)
MON 11:00 GMT 
TUE 00:00 in Tonga (+13)

son todos al mismo tiempo, ¡pero 3 días diferentes!

Tampoco hay un estándar claro sobre las abreviaturas para las zonas horarias y cómo cambian cuando están en horario de verano, por lo que terminas con cosas como esta:

AST Arab Standard Time     UTC+03
AST Arabian Standard Time  UTC+04
AST Arabic Standard Time   UTC+03

El mejor consejo es mantenerse alejado de la hora local tanto como sea posible y apegarse a UTC donde pueda. Solo convierta a horas locales en el último momento posible.

Cuando realice la prueba, asegúrese de probar países en los hemisferios occidental y oriental, con DST en progreso y no, y un país que no utiliza DST (6 en total).


Con respecto a Israel, esto es medio cierto. Aunque la hora para el cambio de horario de verano no es una fecha específica en el calendario juliano, hay una regla basada en el calendario hebreo (hubo un cambio en 2014). De todos modos, la idea general es correcta: estas cosas pueden cambiar y cambian de vez en cuando
Yaron U.

1
Además, AST = Hora estándar del Atlántico. En cuanto al 'mejor consejo', está bien como punto de partida, pero debe leer el resto de esta página y decir una pequeña oración, y podría hacerlo bien por un tiempo.
DavidWalley

20

Para PHP:

La clase DateTimeZone en PHP> 5.2 ya se basa en la base de datos Olson que otros mencionan, por lo que si está haciendo conversiones de zona horaria en PHP y no en la base de datos, está exento de trabajar con archivos Olson (difíciles de entender).

Sin embargo, PHP no se actualiza con tanta frecuencia como el Olson DB, por lo que el simple uso de conversiones de zona horaria de PHP puede dejarle información DST desactualizada e influir en la exactitud de sus datos. Si bien esto no se espera que ocurra con frecuencia, puede ocurrir, y le sucedería si usted tiene una gran base de usuarios en todo el mundo.

Para hacer frente al problema anterior, use el paquete timezonedb pecl . Su función es actualizar los datos de zona horaria de PHP. Instale este paquete con la frecuencia que se actualiza. (No estoy seguro de si las actualizaciones de este paquete siguen exactamente las actualizaciones de Olson, pero parece que se actualiza a una frecuencia que es al menos muy cercana a la frecuencia de las actualizaciones de Olson).


18

Si su diseño puede acomodarlo, ¡ evite la conversión de hora local todos juntos!

Sé que esto puede parecer una locura, pero piense en UX: los usuarios procesan fechas cercanas, relativas (hoy, ayer, el próximo lunes) más rápido que las fechas absolutas (2010.09.17, viernes 17 de septiembre) de un vistazo. Y cuando lo piensa más, la precisión de las zonas horarias (y DST) es más importante cuanto más cerca esté la fecha now(), por lo que si puede expresar fechas / horas en un formato relativo durante +/- 1 o 2 semanas, el resto de las fechas pueden ser UTC y no le importará demasiado al 95% de los usuarios.

De esta manera, puede almacenar todas las fechas en UTC y hacer las comparaciones relativas en UTC y simplemente mostrar las fechas UTC del usuario fuera de su umbral de fecha relativa.

Esto también puede aplicarse a la entrada del usuario (pero generalmente de una manera más limitada). Seleccionar de un menú desplegable que solo tiene {Ayer, Hoy, Mañana, Próximo lunes, Próximo jueves} es mucho más simple y fácil para el usuario que un selector de fecha. Los recolectores de fechas son algunos de los componentes más inductores de dolor del llenado de formularios. Por supuesto, esto no funcionará en todos los casos, pero puede ver que solo se necesita un diseño inteligente para que sea muy potente.


16

Si bien no lo he intentado, un enfoque para los ajustes de zona horaria que me resultaría convincente sería el siguiente:

  1. Almacene todo en UTC.

  2. Cree una tabla TZOffsetscon tres columnas: RegionClassId, StartDateTime y OffsetMinutes (int, en minutos).

En la tabla, almacene una lista de fechas y horas en que cambió la hora local y en qué medida. El número de regiones en la tabla y el número de fechas dependerán del rango de fechas y áreas del mundo que necesite admitir. Piense en esto como si fuera una fecha "histórica", aunque las fechas deberían incluir el futuro hasta cierto límite práctico.

Cuando necesite calcular la hora local de cualquier hora UTC, simplemente haga esto:

SELECT DATEADD('m', SUM(OffsetMinutes), @inputdatetime) AS LocalDateTime
FROM   TZOffsets
WHERE  StartDateTime <= @inputdatetime
       AND RegionClassId = @RegionClassId;

Es posible que desee almacenar en caché esta tabla en su aplicación y usar LINQ o algún otro medio similar para hacer las consultas en lugar de golpear la base de datos.

Estos datos se pueden destilar de la base de datos de dominio público tz .

Ventajas y notas al pie de este enfoque:

  1. No hay reglas integradas en el código, puede ajustar las compensaciones para nuevas regiones o rangos de fechas fácilmente.
  2. No tiene que admitir todos los rangos de fechas o regiones, puede agregarlos según sea necesario.
  3. Las regiones no tienen que corresponder directamente con los límites geopolíticos, y para evitar la duplicación de filas (por ejemplo, la mayoría de los estados en los EE. UU. Manejan el horario de verano de la misma manera), puede tener entradas amplias de RegionClass que se vinculen en otra tabla a listas más tradicionales de estados, países, etc.
  4. Para situaciones como los EE. UU. Donde la fecha de inicio y finalización del horario de verano ha cambiado en los últimos años, esto es bastante fácil de manejar.
  5. Dado que el campo StartDateTime también puede almacenar una hora, el tiempo de cambio estándar de las 2:00 AM se maneja fácilmente.
  6. No en todo el mundo usa un horario de verano de 1 hora. Esto maneja esos casos fácilmente.
  7. La tabla de datos es multiplataforma y podría ser un proyecto de código abierto separado que podría ser utilizado por desarrolladores que usan casi cualquier plataforma de base de datos o lenguaje de programación.
  8. Esto se puede usar para compensaciones que no tienen nada que ver con zonas horarias. Por ejemplo, los ajustes de 1 segundo que ocurren de vez en cuando para ajustar la rotación de la Tierra, ajustes históricos dentro y dentro del calendario gregoriano, etc.
  9. Dado que esto se encuentra en una tabla de base de datos, las consultas de informes estándar, etc. pueden aprovechar los datos sin un viaje a través del código de lógica de negocios.
  10. Esto también maneja las compensaciones de zona horaria si así lo desea, e incluso puede dar cuenta de casos históricos especiales en los que una región está asignada a otra zona horaria. Todo lo que necesita es una fecha inicial que asigne un desplazamiento de zona horaria a cada región con una fecha de inicio mínima. Esto requeriría crear al menos una región para cada zona horaria, pero le permitiría hacer preguntas interesantes como: "¿Cuál es la diferencia en la hora local entre Yuma, Arizona y Seattle, Washington el 2 de febrero de 1989 a las 5:00 am?" (Solo resta una SUMA () de la otra).

Ahora, la única desventaja de este enfoque o de cualquier otro es que las conversiones de la hora local a GMT no son perfectas, ya que cualquier cambio de horario de verano que tenga un desplazamiento negativo en el reloj repite una hora local determinada. Me temo que no es una forma fácil de lidiar con eso, que es una de las razones por las que almacenar las horas locales es una mala noticia en primer lugar.


8
Su idea de base de datos ya se ha implementado como la Base de datos Olson. Si bien el horario de verano crea una superposición que especifica que la zona horaria específica del día puede ayudar a resolver el problema. 2:15 EST y 2:15 EDT son tiempos diferentes. Como se señaló en otras publicaciones que especifican el desplazamiento, también se resuelve la ambigüedad.
BillThor

55
El gran problema con mantener su propia base de datos es mantenerla actualizada. Olson y Windows se mantienen para usted. He tenido más de un caso de tener malas transiciones DST porque las tablas estaban desactualizadas. Extraerlos por completo y confiar en un marco o una base de datos a nivel de sistema operativo es mucho más confiable.
Matt Johnson-Pint

44
No cree su propia base de datos : ¡confíe siempre en la API del sistema!
Alex

15

Recientemente tuve un problema en una aplicación web en la que en una devolución de datos Ajax la fecha y hora que volvía a mi código del lado del servidor era diferente de la fecha y hora servida.

Lo más probable es que tuviera que ver con mi código JavaScript en el cliente que creó la fecha para volver a publicar en el cliente como cadena, porque JavaScript se estaba ajustando para la zona horaria y el horario de verano, y en algunos navegadores el cálculo de cuándo aplicar el horario de verano Parecía ser diferente que en otros.

Al final, opté por eliminar por completo los cálculos de fecha y hora en el cliente, y los publiqué en mi servidor en una clave entera que luego se tradujo a la hora en el servidor, para permitir transformaciones consistentes.

Aprendí de esto: no use cálculos de fecha y hora de JavaScript en aplicaciones web a menos que sea ABSOLUTAMENTE necesario.


Javascript se ejecuta en la máquina del cliente, no en la máquina del servidor. La fecha y hora base de Javascript es la fecha y hora del cliente, no la fecha y hora del servidor.
BalusC

Hola balusc Entiendo esto (de mi publicación original: "script javacode en el cliente que creó la fecha ..."). Mi problema era que cierta máquina cliente procesaba DST de una manera y otras de otra. Por lo tanto, moví todo ese procesamiento del lado del servidor para evitar la rareza del navegador
Joon

@ Joon, y hay errores en las implementaciones de JavaScript que no puede detectar o permitir. Entonces, sí, nunca use cálculos de fecha ECMAScript del lado del cliente para cosas importantes (aunque de lo contrario puede hacer un trabajo bastante bueno).
RobG

14

He tocado esto en dos tipos de sistemas, "sistemas de planificación de turnos (por ejemplo, trabajadores de fábricas)" y "sistemas de gestión dependientes del gas) ...

Los días de 23 y 25 horas son difíciles de manejar, al igual que los turnos de 8 horas que duran 7 horas o 9 horas. El problema es que encontrará que cada cliente, o incluso el departamento del cliente, tienen reglas diferentes que han creado (a menudo sin documentar) sobre lo que hacen en estos casos especiales.

Es mejor no hacer algunas preguntas a los clientes hasta que hayan pagado su software "listo para usar". Es muy raro encontrar un cliente que piense en este tipo de problema por adelantado al comprar software.

Creo que, en todos los casos, debe registrar la hora en UTC y convertirla a / desde la hora local antes de almacenar la fecha / hora. Sin embargo, incluso saber en qué momento se encuentra un tiempo determinado puede ser difícil con el horario de verano y las zonas horarias.


66
Mi novia, una enfermera, trabaja de noche y tienen que escribir la zona horaria durante el cambio de horario de verano. Por ejemplo, 2AM CST vs 2AM CDT
Joe Phillips

1
Sí, esto es común: cuando calcula un promedio diario (civil), debe hacer frente a los días de 23, 24 o 25 horas. Como consecuencia, cuando calculas agregar 1 día, ¡no es agregar 24 horas ! Segundo, no intentes construir tu propio código de zona horaria; solo use sistemas API. Y no olvide actualizar cada sistema implementado para obtener la base de datos actualizada de la zona horaria .
Alex

12

Para la web, las reglas no son tan complicadas ...

  • Del lado del servidor, use UTC
  • Del lado del cliente, use Olson
    • Motivo: las compensaciones UTC no son seguras para el horario de verano (por ejemplo, Nueva York es EST (UTC - 5 horas) parte del año, EDT (UTC - 4 horas) resto del año).
    • Para determinar la zona horaria del lado del cliente, tiene dos opciones:

El resto es solo conversión UTC / local utilizando las bibliotecas de fecha y hora del lado del servidor. Bueno para ir...


2
Este es un buen consejo como punto de partida, pero depende totalmente de la aplicación. Esto podría estar bien para un sitio web amigable, pero si hay algún aspecto legal / jurisdiccional / financiero en su solicitud que alguien pueda demandar (he trabajado en varios), entonces esta es una simplificación excesiva porque hay diferentes tipos de ' tiempo ', como se señaló en otra parte de esta página.
DavidWalley

12

Cuando se trata de aplicaciones que se ejecutan en un servidor , incluidos sitios web y otros servicios de fondo, la aplicación debe ignorar la configuración de zona horaria del servidor.

El consejo común es configurar la zona horaria del servidor en UTC. De hecho, esta es una buena práctica recomendada, pero está ahí como una curita para aplicaciones que no siguen otras prácticas recomendadas. Por ejemplo, un servicio podría estar escribiendo en archivos de registro con marcas de tiempo locales en lugar de marcas de tiempo basadas en UTC, creando así ambigüedades durante la transición de retroceso del horario de verano. Establecer la zona horaria del servidor en UTC corregirá esa aplicación. Sin embargo, la solución real sería que la aplicación inicie sesión con UTC para empezar.

El código del lado del servidor, incluidos los sitios web, nunca debe esperar que la zona horaria local del servidor sea algo en particular.

En algunos idiomas, la zona horaria local puede introducirse fácilmente en el código de la aplicación. Por ejemplo, el DateTime.ToUniversalTimemétodo en .NET se convertirá desde la zona horaria local a UTC, y la DateTime.Nowpropiedad devuelve la hora actual en la zona horaria local. Además, el Dateconstructor en JavaScript utiliza la zona horaria local de la computadora. Hay muchos otros ejemplos como este. Es importante practicar la programación defensiva, evitando cualquier código que use la configuración de zona horaria local de la computadora.

Reserve utilizando la zona horaria local para el código del lado del cliente, como aplicaciones de escritorio, aplicaciones móviles y JavaScript del lado del cliente.


11

Mantenga sus servidores configurados en UTC y asegúrese de que todos estén configurados para ntp o su equivalente.

UTC evita los problemas de horario de verano, y los servidores no sincronizados pueden causar resultados impredecibles que tardan un tiempo en diagnosticarse.


9

Tenga cuidado al tratar con marcas de tiempo almacenadas en el sistema de archivos FAT32: siempre se conserva en las coordenadas de hora local (que incluyen DST; consulte el artículo de msdn ). Me quemé con eso.


Gran punto NTFS no tiene este problema, pero algunas personas todavía usan FAT32, especialmente en las llaves USB.
Matt Johnson-Pint el

7

Otra cosa, asegúrese de que los servidores tengan aplicado el parche actualizado de horario de verano.

Tuvimos una situación el año pasado en la que nuestros tiempos estuvieron constantemente fuera de una hora por un período de tres semanas para los usuarios de América del Norte, a pesar de que estábamos usando un sistema basado en UTC.

Resulta que al final fueron los servidores. Solo necesitaban un parche actualizado aplicado ( Windows Server 2003 ).


6

DateTimeZone::listAbbreviations()Salida de PHP

Este método PHP devuelve una matriz asociativa que contiene algunas zonas horarias 'principales' (como CEST), que por sí mismas contienen zonas horarias 'geográficas' más específicas (como Europa / Amsterdam).

Si está utilizando estas zonas horarias y su información de desplazamiento / DST, es extremadamente importante tener en cuenta lo siguiente:

¡Parece que se incluyen todas las diferentes configuraciones de desplazamiento / DST (incluidas las configuraciones históricas) de cada zona horaria!

Por ejemplo, Europa / Amsterdam se puede encontrar seis veces en la salida de esta función. Dos ocurrencias (desplazamiento 1172/4772) son para el tiempo de Amsterdam utilizado hasta 1937; dos (1200/4800) son para el tiempo que se usó entre 1937 y 1940; y dos (3600/4800) son para el tiempo utilizado desde 1940.

Por lo tanto, no puede confiar en que la información de desplazamiento / DST devuelta por esta función sea ​​actualmente correcta / en uso.

Si desea conocer el desplazamiento / DST actual de una determinada zona horaria, deberá hacer algo como esto:

<?php
$now = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
echo $now->getOffset();
?>

5

Si tiene sistemas de bases de datos que se ejecutan con DST activo, verifique cuidadosamente si deben cerrarse durante la transición en otoño. A Mandy DBS (u otros sistemas también) no le gusta pasar el mismo punto en el tiempo (local) dos veces, que es exactamente lo que sucede cuando retrocede el reloj en otoño. SAP ha resuelto esto con una solución alternativa (en mi humilde opinión): en lugar de hacer retroceder el reloj, simplemente dejan que el reloj interno funcione a la mitad de la velocidad habitual durante dos horas ...


4

¿Estás usando el framework .NET ? Si es así, permítame presentarle el tipo DateTimeOffset , agregado con .NET 3.5.

Esta estructura contiene tanto a DateTimecomo un Offset ( TimeSpan), que especifica la diferencia entre la DateTimeOffsetfecha y la hora de la instancia y la hora universal coordinada (UTC).

  • El DateTimeOffset.Nowmétodo estático devolverá una DateTimeOffset instancia que consta de la hora actual (local) y el desplazamiento local (como se define en la información regional del sistema operativo).

  • El DateTimeOffset.UtcNowmétodo estático devolverá una DateTimeOffsetinstancia que consta de la hora actual en UTC (como si estuviera en Greenwich).

Otros tipos útiles son las clases TimeZone y TimeZoneInfo .


Esta no es una solución al problema presentado.
caradrye

4

Para aquellos que luchan con esto en .NET , vea si vale la pena usar DateTimeOffsety / o TimeZoneInfo.

Si desea utilizar las zonas horarias de IANA / Olson , o si los tipos integrados no son suficientes para sus necesidades, consulte Noda Time , que ofrece una API de fecha y hora mucho más inteligente para .NET.


4

Las reglas comerciales siempre deben funcionar en tiempo civil (a menos que haya una legislación que diga lo contrario). Tenga en cuenta que el tiempo civil es un desastre, pero es lo que la gente usa, así que es lo importante.

Internamente, mantenga las marcas de tiempo en algo como civil-time-segundos-de-época. La época no importa particularmente (estoy a favor de la época de Unix ) pero hace las cosas más fáciles que la alternativa. Imagina que los segundos de salto no existen a menos que estés haciendo algo que realmente los necesite (por ejemplo, seguimiento satelital). La asignación entre las marcas de tiempo y la hora mostrada es el único punto donde se deben aplicar las reglas DST ; las reglas cambian con frecuencia (a nivel global, varias veces al año; culpe a los políticos), por lo que debe asegurarse de no codificar el mapeo. La base de datos TZ de Olson es invaluable.


3
El problema aquí es que el tiempo civil (también conocido como tiempo calendario) no representa correctamente un solo momento en el tiempo. Si toma el enfoque de segundos de la época, ¿realmente tendrá en cuenta cada momento que se omitió o se rebobinó para las transiciones de horario de verano? Probablemente no. La base de época solo funciona contra UTC o alguna otra referencia fija de tiempo instantáneo.
Matt Johnson-Pint el

@MattJohnson De ahí la parte de "reglas de negocio". Si las reglas dicen que algo sucede a las 2:30 de la mañana (o en cualquier momento), sucederá dos veces un día al año y nunca un día al año. Eso es lo que el cliente espera que suceda si no aclara la regla.
user253751

Mantener marcas de tiempo internas en tiempo civil puede ser muy complicado. Manteniéndolo en segundos desde que una época es aún más complicada, diría francamente peligroso. Estoy seguro de que hay personas que lo hacen, y podría ser posible que funcione correctamente la mayor parte del tiempo si tienes mucho cuidado, pero no se puede considerar una mejor práctica o una recomendación general.
Steve Summit

2

Solo quería señalar dos cosas que parecen inexactas o al menos confusas:

Siempre persista el tiempo de acuerdo con un estándar unificado que no se vea afectado por el horario de verano. GMT y UTC han sido mencionados por diferentes personas, aunque UTC parece ser mencionado con mayor frecuencia.

Para (casi) todos los propósitos prácticos de computación, UTC es, de hecho, GMT. A menos que vea una marca de tiempo con un segundo fraccional, está tratando con GMT, lo que hace que esta distinción sea redundante.

Incluya el desplazamiento de la hora local tal como está (incluido el desplazamiento del horario de verano) al almacenar marcas de tiempo.

Una marca de tiempo siempre se representa en GMT y, por lo tanto, no tiene desplazamiento.


1
El desplazamiento de la hora local le permitirá recrear el "tiempo de pared" original del evento. Si no almacena este campo adicional, estos datos se pierden.
nogridbag

Sí, excepto que las compensaciones UTC y GMT son inversas. Por ejemplo, UTC-0700 es lo mismo que GMT + 0700. Realmente, todo lo digital debería estar usando UTC en estos días.
Matt Johnson-Pint

1
@ Matt: ¿estás seguro de que las compensaciones UTC y GMT son inversas? ¿Dónde puedo leer sobre eso?
Reto Höhener

En realidad, creo que antes era incorrecto. GMT y UTC no se invierten ellos mismos. Es que hay implementaciones que las muestran en sentido inverso, como la base de datos IANA / Olson / TZDB. Ver aquí . Otra área que ve compensaciones en inverso es la función getTimezoneOffset () de javascript.
Matt Johnson-Pint

@ MattJohnson: Esos son hacks y deberían ser abolidos.
Alix Axel

2

Aquí está mi experiencia: -

(No requiere ninguna biblioteca de terceros)

  • En el lado del servidor, almacene las horas en formato UTC para que todos los valores de fecha / hora en la base de datos estén en un solo estándar, independientemente de la ubicación de los usuarios, servidores, zonas horarias o DST.
  • En la capa de IU o en los correos electrónicos enviados al usuario, debe mostrar los tiempos de acuerdo con el usuario. Para el caso, debe tener el desplazamiento de la zona horaria del usuario para poder agregar este desplazamiento al valor UTC de su base de datos, lo que dará como resultado la hora local del usuario. Puede tomar el desplazamiento de la zona horaria del usuario cuando se registra o puede detectarlo automáticamente en plataformas web y móviles. Para los sitios web, el método getTimezoneOffset () de la función de JavaScript es un estándar desde la versión 1.0 y es compatible con todos los navegadores. (Ref: http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp )

Esto no funciona cuando considera los cambios de horario de verano. getTimezoneOffsetdevuelve el desplazamiento de la fecha y hora en que lo llama. Ese desplazamiento puede cambiar cuando una zona horaria cambia dentro o fuera del horario de verano. Consulte "zona horaria! = Desplazamiento" en la wiki de etiqueta de zona horaria .
Matt Johnson-Pint

1
Si desea almacenar una alarma como "hacer algo a las 10:00", no puede almacenarla en UTC, debido a los cambios de horario de verano. Debe almacenarlo en relación con la hora local.
Alex

2

El video de Tom Scott sobre zonas horarias en YouTube en el canal Computerphile también tiene una descripción agradable y entretenida del tema. Ejemplos incluyen:

  • Samoa (una isla en el Océano Pacífico) adelanta su zona horaria en 24 horas para facilitar el comercio con Australia y Nueva Zelanda,
  • Cisjordania , donde 2 poblaciones de personas siguen diferentes zonas horarias,
  • El siglo XVIII cambia del calendario juliano al calendario gregoriano (que sucedió en el siglo XX en Rusia).

1

En realidad, kernel32.dll no exporta SystemTimeToTzSpecificLocation. Sin embargo, exporta los dos siguientes: SystemTimeToTzSpecificLocalTime y TzSpecificLocalTimeToSystemTime ...


1

Nunca confíes solo en constructores como

 new DateTime(int year, int month, int day, int hour, int minute, TimeZone timezone)

Pueden lanzar excepciones cuando no existe una fecha y hora determinada debido al horario de verano. En cambio, cree sus propios métodos para crear tales fechas. En ellos, detecte cualquier excepción que ocurra debido al horario de verano y ajuste el tiempo necesario con el desplazamiento de transición. El horario de verano puede ocurrir en diferentes fechas y a diferentes horas (incluso a medianoche para Brasil) según la zona horaria.


1

Solo un ejemplo para demostrar que el tiempo de manejo es el gran desastre descrito, y que nunca puedes ser complaciente. En varios puntos de esta página se han ignorado los segundos bisiestos.

Hace varios años, el sistema operativo Android usaba satélites GPS para obtener una referencia de tiempo UTC, pero ignoraba el hecho de que los satélites GPS no usan segundos intercalares. Nadie se dio cuenta hasta que hubo confusión en la víspera de Año Nuevo, cuando los usuarios de teléfonos Apple y Android hicieron sus cuentas regresivas con aproximadamente 15 segundos de diferencia.

Creo que desde entonces se ha solucionado, pero nunca se sabe cuándo estos 'detalles menores' volverán a atormentarte.


1
  • Nunca, nunca almacene la hora local sin su desplazamiento UTC (o una referencia a la zona horaria); los ejemplos de cómo no hacerlo incluyen FAT32 y struct tmen C.¹
  • Comprender que una zona horaria es una combinación de
    • Un conjunto de compensaciones UTC (por ejemplo, +0100 en invierno, +0200 en verano)
    • reglas para cuándo ocurre el cambio (que puede cambiar con el tiempo: por ejemplo, en la década de 1990, la UE armonizó el cambio como los últimos domingos de marzo y octubre, a las 02:00 hora estándar / 03: 00 DST; anteriormente esto difería entre estados miembros).

¹ Algunas implementaciones de struct tm sí almacenan el desplazamiento UTC, pero esto no lo ha convertido en el estándar.


-4

Al tratar con bases de datos (en particular MySQL , pero esto se aplica a la mayoría de las bases de datos), me resultó difícil almacenar UTC.

  • Las bases de datos generalmente funcionan con la fecha y hora del servidor de forma predeterminada (es decir, CURRENT_TIMESTAMP).
  • Es posible que no pueda cambiar la zona horaria del servidor.
  • Incluso si puede cambiar la zona horaria, es posible que tenga un código de terceros que espera que la zona horaria del servidor sea local.

Me resultó más fácil simplemente almacenar la fecha y hora del servidor en la base de datos, luego dejar que la base de datos convierta la fecha y hora almacenada nuevamente a UTC (es decir, UNIX_TIMESTAMP ()) en las instrucciones SQL. Después de eso, puede usar la fecha y hora como UTC en su código.

Si tiene el 100% de control sobre el servidor y todo el código, probablemente sea mejor cambiar la zona horaria del servidor a UTC.


La hora local (la hora del servidor) puede ser ambigua durante las transiciones de ahorro de luz de estilo "retroceso". No es confiable de usar como lo describió. Puede haber más de una hora UTC que la hora local del servidor podría representar.
Matt Johnson-Pint

La hora local está perfectamente bien si el servidor está ubicado en una zona horaria sana, es decir, una que no hace DST.
sayap
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.