¿Siempre es una buena idea almacenar tiempo en UTC o es este el caso donde es mejor almacenar en horario local?

En general, es una mejor práctica almacenar tiempo en UTC y como se menciona aquí y aquí

Supongamos que hay un evento que vuelve a ocurrir, digamos hora de finalización, que siempre se encuentra en la misma hora local, digamos a las 17:00, independientemente de si el horario de verano está activado o no para esa zona horaria. Y también existe el requisito de no cambiar la hora manualmente cuando el horario de verano se enciende o se apaga para un huso horario en particular. También es un requisito que siempre que otros sistemas soliciten la hora de finalización mediante API (es decir, GetEndTimeByEvent), siempre envíe la hora de finalización en formato UTC.

Método 1: si se decide almacenar en UTC , puede almacenarse en la tabla de la base de datos como se muestra a continuación.

Event UTCEndTime ===================== ABC 07:00:00 MNO 06:00:00 PQR 04:00:00 

Para el primer evento ABC, la hora de finalización en UTC es a las 07:00 a.m. y si se convierte para mostrar desde el UTC a la hora local del 1 de julio de 2012, dará lugar a las 17:00, hora local, y se convertirá el 10 de octubre de 2012 ( la fecha en que DST está activada para la zona horaria) dará como resultado a las 6 pm, que no es la hora de finalización correcta.

Una posible forma en que podría pensar es almacenar el tiempo de DST en la columna adicional y usar ese tiempo cuando la zona horaria tiene activado el horario de verano.

Método 2: Sin embargo, si se almacena como hora local como la siguiente, por ejemplo, para el evento ABC, siempre será a las 17:00 en cualquier fecha, ya que no hay conversión de UTC a hora local.

 Event LocalEndTime ======================= ABC 17:00:00 MNO 16:00:00 PQR 14:00:00 

Y una capa de aplicación convierte la hora local en hora UTC para enviar a otros sistemas a través de (API GetEndTimeByEvent).

¿Sigue siendo una buena idea almacenar la hora en UTC en este caso? Si es así, ¿cómo obtener una hora local constante?

Preguntas relacionadas: ¿Hay alguna vez una buena razón para almacenar la hora no en UTC?

Creo que para responder a esa pregunta, debemos pensar en los beneficios de usar UTC para almacenar marcas de tiempo.

Personalmente creo que el principal beneficio de eso es que siempre se garantiza (en su mayoría) que el tiempo sea constante . En otras palabras, cada vez que se cambia la zona horaria o se aplica DST, no se avanza ni retrocede a tiempo. Esto es especialmente útil en sistemas de archivos, registros, etc. ¿Pero es necesario en tu aplicación?

Piensa en dos cosas. En primer lugar, sobre la hora del cambio horario del horario de verano. ¿Es probable que sus eventos ocurran entre las 2 AM y las 3 AM (el día en que se realiza el cambio de reloj)? ¿Qué debería pasar entonces?

En segundo lugar, ¿estará la aplicación sujeta a cambios reales en la zona horaria? En otras palabras, ¿volará desde Londres a Varsovia y cambiará la zona horaria de su computadora de forma adecuada? ¿Qué debería pasar en ese caso?

Si respondiste no a ambas preguntas, entonces eres mejor con la hora local. Hará que su aplicación sea más simple. Pero si respondiste que al menos una vez, entonces creo que deberías pensarlo más.


Y eso fue todo sobre la base de datos. La otra cosa es el formato de tiempo utilizado internamente por la aplicación, y eso dependerá de lo que realmente va a hacer en ese momento.

Usted lo mencionó exponiendo el tiempo a través de una API. ¿La aplicación consultará la base de datos en cada solicitud? Si almacena el tiempo internamente como UTC, deberá hacerlo o, de lo contrario, asegurarse de que en el horario de verano / cambio de zona horaria los tiempos de caché se ajusten / eliminen.

¿Hará algo con el tiempo en sí? Al igual que la impresión, el evento se producirá en 8 horas o se suspenderá durante ese tiempo. Si es así, entonces UTC probablemente sea mejor. Por supuesto, debes pensar en todos los temas mencionados.

Me gusta pensar de esta manera:

A las computadoras no les importa el tiempo como una representación comprensible para los humanos. No les importan las zonas horarias, el formato de cadena de fecha y hora ni nada de eso. Solo a los humanos les importa cómo interpretar y representar el tiempo.

Deje que la base de datos haga lo que le conviene: almacenar el tiempo como un número, ya sea una época UNIX (cantidad de segundos transcurridos desde 1970-01-01) o una marca de tiempo UTC (sin información de zona horaria o horario de verano). Solo preocúpese por representar el tiempo de una manera humanamente comprensible cuando debe hacerlo. Eso significa que en su aplicación lógica, sistema de informes, aplicación de consola o en cualquier otro lugar, un ser humano estará viendo los datos.

Lo siguiente no se aplicaría a un producto SaaS global con múltiples usuarios, por lo que esta opinión está dirigida a desarrolladores de aplicaciones simples de la “Línea de negocios”.

Almacenar como UTC está bien, pero hay un requisito que causa dolor si haces esto: “¿Puedes escribirme un informe que me muestre cuántas de X ocurren por día?”

Si almacena fechas como UTC, este requisito causará dolor; necesita escribir el código de ajuste de zona horaria en el servidor de aplicaciones y en sus informes; Todas las consultas ad-hoc que realice sobre datos que incluyan criterios de fecha deberán tener esto en cuenta.

Si su aplicación cumple con los siguientes criterios:

  1. Cada instancia se basa en una sola zona horaria.
  2. Las transiciones de zonas horarias generalmente son fuera del horario de oficina o no te importan las “duraciones” de las cosas hasta el nivel que una hora faltante importará.

Le sugiero que almacene la fecha y hora como fecha local, mientras utiliza una biblioteca que lo aísla de los problemas de configuración de la zona horaria del servidor (por ejemplo, Noda.Time en el mundo de .net).

Si sus mensajes entre sistemas usan ISO 8601, y su base de datos está almacenando el origen local time + offset (como datetimeoffset en MSSQL o ISODate en Mongo como ISO 8601 lo captura) y solo está usando DateTimeOffset en .NET o OffsetDateTime en Java o algún equivalente en su código, entonces no se necesitan conversiones, en absoluto. Usted solo lo almacena. Todas las funciones de comparación simplemente funcionarán.

Si convierte a UTC en su persistencia, entonces ha perdido el desplazamiento desde el punto de vista del usuario. Mostrar el momento en que su usuario firmó un documento hace una década es ahora un problema difícil. Trabajar eso desde UTC significará buscar las reglas de DST que estaban en juego en ese momento en ese territorio. Pesadilla.

Creo que la razón por la que todos estamos tan acostumbrados a la conversión a UTC para la persistencia es porque nunca solíamos tener las estructuras de datos / tipos de datos correctos para permitirnos hacer lo correcto.

Solo almacenaría el componente Time solo sin Zone. Siempre que la API deba servirlo, agregue la fecha correcta y conviértala como hora local a UTC para esa fecha.

Base de datos = 17:00 (use una marca de tiempo sin fecha, horas como byte, minutos como byte, cadena)

Retrieve = Fecha donde queremos el evento + Base de datos 17:00 => Convertir esto de local a UTC

De esta forma, siempre servirá la hora correcta en UTC.

En realidad, no está almacenando un punto específico en el tiempo como la mayoría de las API de tiempo suponen. Use intervalos si su base de datos lo admite (PostgreSQL sí) o almacénelo como un número entero que represente el número de segundos (minutos / horas) desde la medianoche o el comienzo correspondiente de la progtwigción (lunes, el primero del mes, etc.). En cualquier caso, ha perdido muchos de los dolores de cabeza de preocuparse por cómo se maneja el “tiempo” entre los sistemas, y le ha agregado un dolor de cabeza muy leve para convertir segundos a la hora del día en su vista.