zona horaria findsystemtimezonebyid example datetime timezone utc dst datetimeoffset

datetime - findsystemtimezonebyid - Mejores prácticas de horario de verano y zonas horarias



datetimeoffset vs datetime (30)

Espero hacer esta pregunta y las respuestas a 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 haga

Muchos sistemas dependen de mantener la hora precisa, el problema es con los cambios en la hora debido al horario de verano: adelantar o retrasar el reloj.

Por ejemplo, uno tiene reglas de negocios en un sistema de toma de pedidos que depende 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 un sinfín de escenarios, este es simplemente uno ilustrativo.

  • ¿Cómo ha resuelto el problema del horario de verano?
  • ¿Qué suposiciones 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 excelentes, pero también me gustaría ver los detalles, especialmente si solo están disponibles en una plataforma.


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 compensación / DST, es extremadamente importante darse cuenta de lo siguiente:

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

Por ejemplo, Europa / Ámsterdam se puede encontrar seis veces en la salida de esta función. Dos ocurrencias (desplazamiento 1172/4772) son para el tiempo de Ámsterdam utilizado hasta 1937; dos (1200/4800) corresponden al tiempo utilizado 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 compensación / 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(); ?>


Resumen de respuestas y otros datos: (por favor agregue el suyo)

Hacer:

  • Cuando 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 tiempo Zulu o Z ).
  • Si, por el contrario, opta por persistir una hora utilizando un valor de hora local, incluya la compensación de la hora local para esta hora en particular desde UTC (esta compensación puede cambiar a lo largo del 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 tipo de conjunto de datos que puede almacenar ambos en un solo campo.
  • Cuando almacene las marcas de tiempo como un valor numérico, use el tiempo de Unix , que es el número de segundos completos desde 1970-01-01T00:00:00Z (excluyendo los segundos de salto). Si necesita una mayor precisión, utilice milisegundos en su lugar. Este valor siempre debe basarse en UTC, sin ningún ajuste de zona horaria.
  • Si luego necesita modificar la marca de tiempo, incluya la ID de zona horaria original para poder determinar si el desplazamiento puede haber cambiado con respecto al valor original registrado.
  • Cuando se programan eventos futuros, generalmente se prefiere la hora local en lugar de la UTC, ya que es común que la compensación cambie. Ver respuesta y entrada de blog .
  • Cuando almacene 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 tal 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 las 12:00 del mediodía, en lugar de las 00:00 de la medianoche como una hora de representación más segura en 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, o use Joda Time para Java 7 o inferior.
  • Si usa .NET , considere usar Noda Time .
  • Si usa .NET sin Noda Time, considere que DateTimeOffset es a menudo 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 de moment-timezone .
  • Si usa PHP> 5.2, use las conversiones de zonas horarias nativas proporcionadas por las clases DateTimeZone y DateTimeZone . Tenga cuidado al usar DateTimeZone::listAbbreviations() - vea la respuesta . Para mantener PHP con los datos de Olson actualizados, instale periódicamente el paquete PECL de timezonedb ; ver respuesta .
  • Si usa C ++, asegúrese de usar una biblioteca que use la implementación correcta de la base de datos de zona horaria de IANA . Estos incluyen cctz , ICU y la biblioteca "tz" de Howard Hinnant .
    • No utilice Boost para las conversiones de zona horaria. Si bien su API afirma ser compatible con los identificadores estándar de IANA (también conocido como "zoneinfo"), los asigna de manera aproximada a los datos de estilo POSIX, sin tener en cuenta el rico historial de cambios que puede haber tenido cada zona. (Además, el archivo ha quedado fuera de mantenimiento.)
  • Si usas óxido, usa el chrono .
  • La mayoría de las reglas de negocios usan tiempo civil, en lugar de UTC o GMT. Por lo tanto, planee convertir las marcas de tiempo UTC en 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 "saltar hacia adelante" y "retroceder". Sin embargo, en 2007, los EE. UU. Cambiaron las fechas en que se modificaron los relojes. Esto ahora significa que durante las 48 semanas del año, la diferencia entre la hora de Londres y la hora de Nueva York es de 5 horas y de 4 semanas (3 en la primavera, 1 en 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) debe almacenar para la recuperación correcta; consulte "Tipos de tiempo" en esta respuesta
  • Mantenga sincronizados sus archivos de sistema operativo, base de datos y datos de aplicaciones, entre ellos y el resto del mundo.
  • En los servidores, configure los relojes de hardware y los relojes del sistema operativo 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. ver 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 la configuración predeterminada.
  • Utilice 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 (por ejemplo, programa de televisión semanal), recuerde que la hora cambia con el horario de verano y será diferente en las distintas zonas horarias.
  • Consulte siempre los valores de fecha y hora como inclusivo inferior inclusivo, exclusivo límite superior ( >= , < ).

No hagas

  • No confunda una "zona horaria", como America/New_York con una "zona horaria compensada", como -05:00 . Son dos cosas diferentes. Vea la etiqueta de la zona horaria wiki .
  • No use el objeto Date de JavaScript para realizar cálculos de fecha y hora en navegadores web más antiguos, ya que ECMAScript 5.1 y anteriores tienen una falla de diseño que puede usar el horario de verano de manera incorrecta. (Esto fue corregido 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 breve de varios escenarios válidos que se describen anteriormente en este documento. En su lugar, use la referencia de tiempo adecuada para los datos con los que está trabajando. (La marca de tiempo puede usar UTC, pero la programación de tiempo futuro y los valores de solo fecha no deberían).

Pruebas:

  • Cuando realice las pruebas, asegúrese de realizar pruebas en los países de los hemisferios occidental, oriental, septentrional y Southern (de hecho, en cada cuarto del mundo, de modo que hay 4 regiones), con DST en progreso y no (da 8), y un país que sí. No utilice DST (otros 4 para cubrir todas las regiones, lo que hace 12 en total).
  • Pruebe la transición del horario de verano, es decir, cuando se encuentra actualmente en el horario de verano, seleccione un valor de tiempo del invierno.
  • Pruebe los casos de límites, como una zona horaria que es UTC + 12, con horario de verano, lo que hace 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.
  • Probar zonas horarias de media hora, al menos.

Referencia:

Otro:

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

Cruzar el límite de "tiempo de computadora" y "tiempo de personas" es una pesadilla. La principal es que no hay ningún tipo de estándar para las reglas que rigen las zonas horarias y el horario 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, por ejemplo, Israel, Brasil, deciden cada año cuándo tienen su horario de verano, por lo que es imposible saber de antemano cuándo (si) el horario de verano estará en vigencia. Otros tienen reglas fijas (ish) sobre cuándo está en vigencia el horario de verano. Otros países no utilizan DST como todos.

Las zonas horarias no tienen que ser las 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 los horarios locales tanto como sea posible y apegarse a UTC donde pueda. Convierta solo a horarios locales en el último momento posible.

Cuando realice las pruebas, asegúrese de realizar pruebas en los países de los hemisferios occidental y oriental, con el horario de verano en curso y no en un país que no usa horario de verano (6 en total).


En general, incluya el desplazamiento de la hora local (incluido el desplazamiento de DST) en las marcas de tiempo almacenadas: solo UTC no es suficiente si más adelante desea mostrar la marca de tiempo en su zona horaria original (y 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 de Unix, desplazamiento en minutos) o ISO 8601 .


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, uno generalmente trata con 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 "físico" de tiempo es un punto en la línea de tiempo universal continua con la que trata la física (ignorando la relatividad, por supuesto). Este concepto puede codificarse-persistir adecuadamente en UTC, por ejemplo (si puede ignorar los segundos de salto).

Un tiempo "civil" es una especificación de fecha y hora que sigue normas civiles: un punto de tiempo aquí se especifica completamente mediante un conjunto de campos de fecha y hora (Y, M, D, H, MM, S, FS) más una 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 en conjunto permiten (en principio) mapear de una representación a otra. Pero los instantes de tiempo civil y físico son tipos de magnitudes fundamentalmente diferentes, y deben mantenerse separados conceptualmente y ser tratados de manera diferente (una analogía: matrices de bytes y cadenas de caracteres).

El tema es confuso porque hablamos de este tipo de eventos de manera intercambiable, y porque los tiempos civiles están sujetos a cambios políticos. El problema (y la necesidad de distinguir estos conceptos) se hace más evidente para los eventos en el futuro. Ejemplo (tomado de mi discusión here .

John registra en su calendario un recordatorio para algún evento en la fecha 2019-Jul-27, 10:30:00 , 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 en

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 lo que Juan 2019-Jul-27, 10:30:00 TZ=Chile/Santiago conceptualmente cuando dijo al calendario "Por favor, llámeme al 2019-Jul-27, 10:30:00 TZ=Chile/Santiago ".

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

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

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


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 la hora para / desde la representación canónica (UTC). La fecha y hora no UTC es presentación (sigue la zona horaria local del usuario), la hora UTC es modelo (sigue siendo única para los niveles de back-end y medios).

Además, decida cuál es su audiencia real, qué no tiene que atender y dónde traza la línea . No toque calendarios exóticos a menos que tenga clientes importantes allí y luego considere servidores separados para el 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 de .NET o una tabla SQL), pero proporcione una forma para que el usuario final elija las anulaciones si la fecha y la hora es fundamental para sus usuarios.

Si hay obligaciones históricas de auditoría involucradas (por ejemplo, informar exactamente cuándo Jo en AZ pagó una factura hace dos años en septiembre) , mantenga la hora UTC y local para el registro (sus tablas de conversión cambiarán en el transcurso del tiempo).

Defina la zona horaria de referencia de tiempo para los datos que vienen en forma masiva , como archivos, servicios web, etc. Diga que la compañía de la costa este tiene un centro de datos en CA: necesita 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, siempre solicite que la zona horaria y / o la zona de referencia se definan explícitamente . Puede recibir fácilmente el tiempo con la compensación de PST, pero en realidad es EST, ya que ese es el tiempo de referencia del cliente y los registros se exportaron a un servidor que está en PST.


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

Tipos de tiempos

Hay cuatro momentos diferentes que debes 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 la televisión: por ejemplo, un programa de televisión en particular se emite a las 9 pm hora local de todo el mundo. Importante cuando piense 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. Tiempo recurrente: por ejemplo: un programa de televisión está activado todos los lunes a las 9 pm, incluso cuando cambia el horario de verano.

También hay hora histórica / alternativa. Estos son molestos porque no se pueden asignar al tiempo estándar. Por ejemplo: fechas julianas, fechas según un calendario lunar en Saturno, el calendario Klingon.

El almacenamiento de las 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 se encuentra en una situación crítica). 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 una marca de tiempo creada para poder saber si una definición de zona horaria cambió antes o después de la creación de este evento. Esto es necesario si necesita mostrar datos históricos.

Tiempos de almacenamiento

  • Almacenar siempre el tiempo en UTC
  • Convertir a la 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 hora y el desplazamiento. Esto es necesario porque los gobiernos a veces cambian los significados de sus zonas horarias (por ejemplo: las fechas de horario de verano cambiadas por el gobierno de EE. UU.), Y su aplicación necesita manejar las cosas con gracia ... por ejemplo: la fecha y hora exacta en que los episodios de LOST mostraron las reglas de DST antes y después cambiado

Compensaciones y nombres

Un ejemplo de lo anterior sería:

El partido de la final de la copa mundial de fútbol ocurrió 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 la que tuvo lugar la final de la WCS de 2010, incluso si cambia la definición de la zona horaria sudafricana, y poder mostrarla a los espectadores en su zona horaria local en el momento en que consulten la base de datos.

Hora del sistema

También debe mantener sincronizados el sistema operativo, la base de datos y los archivos de datos de la aplicación, tanto entre sí como con el resto del mundo, y realizar pruebas exhaustivas al actualizar. No es extraño que una aplicación de terceros de la que dependes 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 estén configurados para usar UTC también. Esto se hace evidente cuando necesita copiar archivos de registro de apache rotados por hora desde servidores en múltiples 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 tiene que escribir datos matemáticos en la cabeza cuando salta de una caja a otra y necesita comparar las 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() javascript Date.getTime() . Estos están bien cuando se usan como identificadores opacos, o cuando se hacen cálculos de fecha 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 es posible que no tengan una batería que funcione para su reloj de BIOS.

Trivialidades

Finalmente, los gobiernos a veces hacen cosas muy raras:

La hora 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 utilizando el formato HH: MM.

Ok, creo que he terminado.


Para PHP:

La clase DateTimeZone en PHP> 5.2 ya se basa en la base de datos de 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 los archivos de Olson (los que son difíciles de entender).

Sin embargo, PHP no se actualiza con tanta frecuencia como la base de datos de Olson, por lo que el uso de las conversiones de zona horaria de PHP puede dejarlo con información DST obsoleta e influir en la exactitud de sus datos. Si bien no se espera que esto ocurra con frecuencia, puede suceder, y sucederá si tiene una gran base de usuarios en todo el mundo.

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


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

  1. Almacenar todo en UTC.

  2. Cree una tabla TZOffsets con 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é cantidad. La cantidad de regiones en la tabla y la cantidad 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 en algún límite práctico.

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

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

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

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

Ventajas y notas a pie de página de este enfoque:

  1. No se incluyen reglas en el código, puede ajustar las compensaciones para nuevas regiones o rangos de fechas fácilmente.
  2. No es necesario que admita todos los intervalos 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 amplias entradas de clase de clase que se vinculan en otra tabla a listas más tradicionales de Estados, países, etc.
  4. Para situaciones como EE. UU. En las que 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. Ya 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 todas partes del mundo se usa un DST 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ían usar los 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 las zonas horarias. Por ejemplo, los ajustes de 1 segundo que ocurren de vez en cuando para ajustarse a la rotación de la Tierra, los ajustes históricos al calendario gregoriano y dentro del mismo, etc.
  9. Como 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 controla 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 reste un SUM () del otro).

Ahora, la única desventaja de este enfoque o cualquier otro es que las conversiones de 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, lo cual es una de las razones por las que almacenar las horas locales es una mala noticia.


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

Sé que para algunos esto puede parecer una locura, pero piense en UX: los usuarios procesan fechas cercanas (de hoy, ayer, el próximo lunes) más rápidas 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 el horario de verano) es más importante cuanto más cerca está la fecha now() , por lo que si puede expresar fechas y fechas en un formato relativo durante +/- 1 o 2 semanas, El resto de las fechas puede ser UTC y no 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 Relativo.

Esto también puede aplicarse a la entrada del usuario también (pero generalmente de una manera más limitada). La selección 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 fechas. Los recolectores de fecha son algunos de los componentes más inductores de llenado de formularios. Por supuesto, esto no funcionará en todos los casos, pero se puede ver que solo se necesita un poco de diseño inteligente para que sea muy poderoso.


ftp://elsie.nci.nih.gov/pub conocer la base de datos Olson tz , 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) para 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 en 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 están en el dominio público.

Esta es la fuente de nombres de zonas horarias como America / Los_Angeles (y sinónimos como US / Pacific).

Si necesita realizar un seguimiento de las diferentes zonas, necesita la base de datos Olson. Como otros lo han recomendado, también desea almacenar los datos en un formato fijo (normalmente es UTC 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 la hora y el nombre de la zona horaria; Eso puede hacer una diferencia más adelante. Además, saber 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 probablemente se especifique 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 legal (ahora desestimada) contra los mantenedores por infracción de derechos de autor. La base de datos de zona horaria ahora se administra bajo los auspicios de la IANA , la Autoridad de Números Asignados de Internet, y hay un enlace en la página principal a la "Base de datos de zona horaria" . La lista de correo de discusión ahora es [email protected] ; La lista de anuncios es [email protected] .


El video de Tom Scott sobre las 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) está avanzando su zona horaria en 24 horas para facilitar el comercio con Australia y Nueva Zelanda,
  • Cisjordania , donde 2 poblaciones de personas están siguiendo diferentes zonas horarias,
  • Cambios del siglo XVIII del calendario juliano al calendario gregoriano (que ocurrió en el siglo XX en Rusia).

Aquí está mi experiencia: -

(No requiere ninguna biblioteca de terceros)

  • En el lado del servidor, almacenar los tiempos 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 UI o en los correos electrónicos enviados al usuario, debe mostrar los tiempos según el usuario. En ese caso, debe tener el desplazamiento de zona horaria del usuario para poder agregar este desplazamiento al valor UTC de su base de datos, lo que resultará en la hora local del usuario. Puede tomar el desplazamiento de la zona horaria del usuario cuando se está registrando o puede detectarlos automáticamente en plataformas web y móviles. Para los sitios web, la función de JavaScript del método getTimezoneOffset () 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 )

Hace poco tuve un problema en una aplicación web en la que, en un post-back de Ajax, la fecha y hora de volver a mi código del lado del servidor era diferente de la fecha y hora de la fecha de entrega.

Lo más probable es que tuviera que ver con mi código JavaScript en el cliente que construyó la fecha para volver a publicar en el cliente como una 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 a los demás.

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

Aprendí de esto: no utilice los cálculos de fecha y hora de JavaScript en las aplicaciones web a menos que tenga que hacerlo ABSOLUTAMENTE.


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

Los días largos de 23 y 25 horas son un dolor al que deben enfrentarse, por lo que son los turnos de 8 horas que toman 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 al cliente hasta después de que hayan pagado por su software "disponible". 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 convertir a / desde la hora local antes de guardar la fecha / hora. Sin embargo, incluso saber en qué hora se encuentra puede ser difícil con el horario de verano y las zonas horarias.


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

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


Nunca confíe 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 determinada debido al horario de verano. En su lugar, construye tus propios métodos para crear tales fechas. En ellos, detecte las excepciones que se produzcan debido al horario de verano y ajuste el tiempo necesario con el desplazamiento de transición. DST puede ocurrir en diferentes fechas y en diferentes horas (incluso a la medianoche para Brasil) de acuerdo con la zona horaria.


Otra cosa es asegurarse de que los servidores tengan aplicado el parche actualizado de ahorro de luz diurna.

Tuvimos una situación el año pasado en la que nuestros tiempos se agotaron constantemente durante una semana durante un período de tres semanas para los usuarios de Norteamérica, 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 ).


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

  • En el lado del servidor, use UTC
  • Del lado del cliente, use Olson
    • Motivo: las compensaciones UTC no son seguras durante el día (p. Ej., Nueva York es EST (UTC - 5 horas) parte del año, EDT (UTC - 4 horas) el resto del año).
    • Para la determinación de 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 servidor. Bueno para ir...


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

Siempre persistir el tiempo de acuerdo con un estándar unificado que no se ve afectado por el ahorro de luz diurna. GMT y UTC han sido mencionados por diferentes personas, aunque UTC parece mencionarse con mayor frecuencia.

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

Incluya el desplazamiento de hora local tal como está (incluido el desplazamiento de DST) cuando almacene marcas de tiempo.

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


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

Esta estructura contiene una DateTimey una compensación ( 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 DateTimeOffsetinstancia que consiste en 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 consiste en la hora actual en UTC (como si estuviera en Greenwich).

Otros tipos útiles son las clases TimeZone y TimeZoneInfo .


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 el servidor datetime 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, puede tener un código de terceros que espera que la zona horaria del servidor sea local.

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

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


Cuando se trata de aplicaciones que se ejecutan en un servidor , incluidos sitios web y otros servicios de back-end, la configuración de zona horaria del servidor debe ser ignorada por la aplicación.

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 curita para aplicaciones que no siguen otras mejores prácticas. 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 solucionará esa aplicación. Sin embargo, la solución real sería que la aplicación inicie sesión con UTC para comenzar.

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á de 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 del equipo. 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.


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


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 así como civil-segundos-segundos-desde la época. La epoch no importa en particular (yo prefiero la época de Unix ) pero hace las cosas más fáciles que la alternativa. Pretenda que leap-seconds no existen a menos que esté haciendo algo que realmente los necesita (por ejemplo, seguimiento por satélite). El mapeo entre las marcas de tiempo y la hora mostrada es el único punto donde se deben aplicar las reglas de DST ; las reglas cambian con frecuencia (a nivel global, varias veces al año; culpar a los políticos), por lo que debe asegurarse de no codificar el mapeo. La base de datos TZ de Olson es invaluable.


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

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


Si por casualidad mantiene sistemas de bases de datos que se ejecutan con DST activo, verifique cuidadosamente si es necesario apagarlos durante la transición en el 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 se atrasa el reloj en otoño. SAP resolvió esto con una solución alternativa (en mi opinión, realmente ordenada): en lugar de hacer retroceder el reloj, dejaron que el reloj interno funcionara a la mitad de la velocidad habitual durante dos horas ...


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 de salto.

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

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


Tenga cuidado cuando se trata de marcas de tiempo almacenados en el sistema de archivos FAT32 - que siempre se conserva en coordenadas de la hora local (que incluyen el horario de verano - véase el artículo de MSDN ). Me quemé en eso.


  • Nunca, nunca almacene la hora local sin su desplazamiento UTC (o una referencia a la zona horaria): 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 la conmutación (que puede cambiar con el tiempo: por ejemplo, en la década de 1990, la UE armonizó la conmutación como los últimos domingos de marzo y octubre, a las 02:00 hora estándar / 03: 00 DST; anteriormente esto era diferente entre los Estados miembros).

Implement Algunas implementaciones de struct tmdo almacenan el desplazamiento UTC, pero esto no se ha convertido en el estándar.