Pregunta

¿Guardar todo en GMT?

¿Guardar todo tal como se ingresó con un desplazamiento incrustado?

¿Haces los cálculos cada vez que renderizas?

¿Mostrar tiempos relativos "hace 1 minuto"?

¿Fue útil?

Solución

Tienes que almacenar en UTC; si no lo haces, tus informes históricos y tu comportamiento durante cosas como el horario de verano desaparecen...divertido.GMT es una hora local, sujeta al horario de verano en relación con UTC (que no lo es).

La presentación a usuarios en diferentes zonas horarias puede ser una verdadera bastarda si estás almacenando la hora local.Es fácil ajustarlo a local si sus datos sin procesar están en UTC: ¡simplemente agregue el desplazamiento de su usuario y listo!

Joel habló sobre esto en uno de los podcasts (de manera indirecta): dijo almacenar sus datos en la mayor resolución posible (busca 'fidelidad'), porque siempre puedes morderlo cuando vuelva a apagarse.Por eso digo que lo almacene como UTC, ya que la hora local debe ajustarse para cualquiera que no esté en esa zona horaria, y eso es mucho trabajo duro.Y debe almacenar si, por ejemplo, el horario de verano estaba vigente cuando almacenó la hora.¡Puaj!

A menudo, en las bases de datos del pasado almacené dos: UTC para ordenar y hora local para mostrar.De esta forma ni el usuario ni el ordenador se confunden.

Ahora, en cuanto a mostrar:Claro, puedes hacer lo de "hace 3 minutos", pero solo si almacenas UTC; de lo contrario, los datos ingresados ​​en diferentes zonas horarias harán cosas como mostrarse como "hace -4 horas", lo que asustará a la gente.Si va a mostrar una hora real, a la gente le encanta tenerla en su hora local, y si se ingresan datos en múltiples zonas horarias, solo puede hacerlo con facilidad si almacena UTC.

Otros consejos

La respuesta, como siempre, es "depende".

Depende de lo que esté describiendo en ese momento y de cómo se le proporcionaron los datos.La clave para decidir cómo almacenar los valores de tiempo es decidir si está perdiendo información al eliminar la zona horaria, además de no sorprender a sus usuarios.

Existen claros beneficios al almacenar datos en un time_t UTC: es un int único, lo que permite una clasificación rápida y un almacenamiento sencillo.

Veo que el problema se divide en áreas específicas:

  1. Información histórica
  2. Datos futuros a corto plazo
  3. Datos futuros a largo plazo

Con las siguientes subclases en cada una:

  1. Sistema proporcionado
  2. Proporcionado por el usuario

Veámoslos uno por uno.

Sistema proporcionado:Recomendaría ejecutar sistemas en UTC, así evitará el problema de la zona horaria y nuevamente, no se verá ninguna pérdida de información (siempre es UTC).

Información histórica:Se trata de cosas como archivos de registro del sistema, estadísticas de procesos, seguimiento, fechas/horas de comentarios, etc.Los datos no cambiarán y el descriptor de zona horaria no cambiará retroactivamente.Para este tipo de datos, no se pierde información al almacenar la información en UTC independientemente de la zona horaria en la que se proporcionó.Entonces, elimine la zona horaria.

Datos futuros a largo plazo:Estos son eventos que están lo suficientemente lejos en el futuro o seguirán sucediendo.Si se mantienen disponibles el tiempo suficiente, se garantiza que los descriptores de zona horaria cambiarán.Un buen ejemplo de este tipo de datos es "La reunión semanal de gestión".Estos son datos que se ingresan una vez y se espera que sigan funcionando a perpetuidad.Para estos valores, es importante determinar si lo proporciona el sistema o el usuario.Para los datos proporcionados por el usuario, la hora debe almacenarse con la zona horaria del creador; cualquier otra cosa resultará en la pérdida de información.¡Esta pérdida de información se hace evidente cuando la definición de zona horaria cambia y el creador muestra la hora con un valor completamente diferente!

Como ha indicado Bwooce, existe cierta confusión cuando el creador y el espectador se encuentran en diferentes zonas horarias.En ese caso, esperaría que la aplicación indique qué valores de tiempo se han movido debido a un cambio de zona horaria con respecto a sus ubicaciones anteriores.

Datos futuros a corto plazo:Estos son datos que rápidamente se convertirán en históricos o que solo serán válidos por un corto período de tiempo.Algunos ejemplos podrían ser cronómetros de intervalos, transiciones de calificación, etc.Para estos datos, dado que la probabilidad de que la definición cambie entre la creación del valor y el momento en que se vuelve histórico es baja, podría ser posible eliminar la zona horaria.Sin embargo, he descubierto que estos valores tienen la mala costumbre de convertirse en "datos futuros a largo plazo".

Una vez que haya decidido almacenar la zona horaria, se debe tener cuidado con la forma en que se almacena.

  • No almacene la zona horaria como un desplazamiento ni el descriptor completo.

Si almacena una zona horaria como compensación, ¿qué hace si la zona horaria cambia?¿Revisa el sistema y realiza un cambio general en los datos existentes?Si lo hace, habrá cometido errores en los valores históricos.Buenos ejemplos de este fallo son Oracle e iCal.Oracle almacena información de zona horaria como una diferencia con respecto a UTC e iCal incluye el descriptor completo de la zona horaria de creación.

  • Guárdelo como un nombre.

Esto permite que la definición de la zona horaria cambie sin tener que modificar los valores existentes que tiene.Hace que la clasificación sea más difícil, ya que cualquier índice que se genere puede no ser válido si cambian los datos de la zona horaria.

Si los desarrolladores continúan almacenando todo en UTC, independientemente de la zona horaria, seguiremos viendo los problemas que hemos visto con el último lote de cambios de zona horaria.

En una organización, las secretarias tenían que imprimir los calendarios de sus equipos antes de la fecha del horario de verano y luego imprimirlos nuevamente después del cambio.Finalmente, compararon los dos y recrearon todas las citas que se habían movido.Por supuesto, se perdieron varios, y hubo varias semanas de dolor hasta que se alcanzó la antigua fecha de horario de verano y los horarios volvieron a ser correctos.

Josh tiene toda la razón, pero tengo una sutil advertencia que explicar.Este es un caso sin una respuesta correcta con respecto a eventos y zonas horarias futuros.

Consideremos el caso de una cita repetida.Ocurre a las 0000 GMT (para simplificar), que son las 1200 NZST (hora estándar de Nueva Zelanda) y las 1000 AEST en Sydney, Australia.

Cuando el horario de verano entre en vigor en una zona, ¿qué debería ocurrir con la cita?Deberia:

1a.Si el cambio de TZ está en la zona del "propietario" de la cita (¿quién lo reservó), entonces intenta permanecer en el mismo tiempo de reloj (por ejemplo, 10:00 a.m.)?
1b.Si el cambio de TZ está en una de las otras zonas de asistentes de la reunión, entonces no hay cambio

Consecuencias:Se mueve para todos los demás, inesperadamente, debido al cambio de los propietarios, pero permanece "la reunión de las 10 a.m." en lo que respecta al propietario.

'2.Como arriba, pero al revés.

Consecuencias:Se mueve para el propietario de la reunión (la reunión de las 10 a. m. se convierte en la reunión de las 9 a. m., o v/v), lo que puede ser de esperar, pero resulta inconveniente.Permanece en el mismo horario de escritorio para los demás asistentes hasta que realicen su propia transición TZ.

Ninguno de los dos es perfecto.Considere el caso de dos citas, una reservada por la Persona A que ocurre a las 10 a.m. hora local, la otra reservada por la Persona B con la Persona A como asistente que ocurre a las 9 a.m.Si la Persona A y la Persona B están en TZ diferentes, entonces un cambio de horario de verano podría fácilmente causar que se reserven dos veces.

Si en este punto estás un poco torcido, lo entiendo perfectamente.

El punto detrás de este ejemplo es que para realizar cualquiera de estos comportamientos correctamente es necesario conocer no solo la versión UTC de la hora local, sino también la TZ (y no la compensación) en la que se encontraba el propietario cuando la reservó.De lo contrario no te queda más remedio que tomar la opción 2, en silencio, sin siquiera informar a nadie que las cosas han cambiado ya que los horarios GMT no cambian y solo cambia la presentación… ¿no?(no, esta es la trampa, la presentación importa cuando la reunión de las 10 a.m. se desarrolla por sí sola)

Debo darle crédito a mi colega y amigo Jason Pollock por esta idea.Leer su punto de vista aquí, y la discusión de seguimiento iCal y VTIMEZONE aquí.

Almacenar todo en GMT/UTC me parece lo más lógico.Luego puede mostrar la fecha y la hora en cada zona horaria que desee.

Algunas advertencias:

  1. Si un tiempo solo se especifica como un tiempo de reloj de pared y esa es la representación principal, entonces no es un tiempo absolutamente especificado.Debe (y no puede) convertirlo en cualquier representación GMT.P.EJ.9:00 am todas las mañanas.En otras palabras:Esta no es la hora (fecha).
  2. Si ahorra una fecha y hora de una cita futura, debe usar el desplazamiento a GMT especificado por la zona horaria de entrada y el el momento en el tiempo mismo.Entonces, si es una cita en verano hecha en invierno en EGEuropa occidental, es +2: 00, aunque el desplazamiento normal (tiempo de invierno) es +1: 00.Esto resolverá el problema de calendario que BWOOCE mencionó.
  3. Por supuesto, lo mismo que se aplica al uso del desplazamiento correcto mientras se convierte en GMT se aplica al convertirse en una fecha y hora en cualquier zona horaria en particular.

Afortunadamente, cuando se usa correctamente, el tipo DateTime (.NET) se encarga de todos los detalles sangrientos de mantener calendarios, etc.para ti y todo esto debería ser muy fácil cuando sabes cómo funciona.

Personalmente, no veo ninguna razón para no almacenar todo en GMT y luego usar la zona horaria local de los usuarios para mostrar la hora correspondiente a ellos.

Si desea mostrar la hora relativa, obviamente aún necesita la hora y hacer una traducción, pero si desea hacer la traducción, creo que GMT sigue siendo su mejor opción.

Entonces realicé un pequeño experimento con el servidor MSSQL.

Creé una tabla y agregué una fila con la zona horaria localizada actual (Australia).Luego cambié mi fecha y hora para que fuera GMT y agregué otra fila.

Aunque esas filas se agregaron con aproximadamente 10 segundos de diferencia, aparecen en el servidor SQL como si estuvieran con 10 horas de diferencia.

Al menos, al menos me dice que debería almacenar las fechas de manera consistente, lo que, para mí, agrega peso al argumento para almacenarlas como GMT.

MS Dynamics almacena GMT y luego, a nivel de usuario, conoce su zona horaria en relación con GMT.Luego le muestra elementos en su zona horaria.

Sólo pensé en comentarlo, ya que es un grupo bastante grande en MS y así es como decidieron manejarlo.

Prefiero almacenar todo con la zona horaria.El cliente puede decidir de qué manera se presentará más adelante.Mi biblioteca favorita para convertir es la Base de datos PostgreSQL.

Eche un vistazo aquí, el w3c ha hecho un excelente trabajo respondiendo la pregunta.

Mire los casos de uso.

http://www.w3.org/TR/timezone/

Tenga en cuenta que recomiendan almacenar las fechas y horas como UTC, no como GMT, ya que GMT está sujeto al horario de verano.

Me gusta almacenar en GMT y mostrar sólo relativo ("hace unos 10 segundos", "hace 5 meses").Los usuarios no necesitan ver marcas de tiempo reales en la mayoría de los casos de uso.

Ciertamente hay excepciones, y una aplicación individual puede tener muchas de ellas, por lo que no puede ser una respuesta "unidireccional".Cosas que necesitan una fuerte capacidad de auditoría (p. ej.votación), y los sistemas donde el tiempo es parte del dominio del discurso (astronomía, investigación científica) podrían exigir que se muestren al usuario marcas de tiempo verdaderas.

Sin embargo, la mayoría de las aplicaciones son más fáciles de entender con un tiempo relativo simple.

Normalmente solo uso el tiempo Unix.No necesariamente es seguro para el futuro, pero funciona bastante bien.

Almacene siempre en GMT (o UTC).Desde allí es fácil convertir a cualquier valor de zona horaria local.

Las fechas deben almacenarse como UTC A MENOS que sean datos proporcionados por el usuario y NO PUEDA saber en qué zona horaria el usuario pretendía que estuvieran esos datos.A veces (muy, muy raramente) solo necesita almacenar los componentes de hora, minutos, segundos, día, mes y año sin ninguna zona horaria para poder escupirlos al usuario.Ahora, para nuevos desarrolladores o si no está seguro, almacene UTC y estará 99% correcto.

Pero no se deje engañar creyendo que esto funciona el 100% de las veces, en todos los casos, todo el tiempo.No es asi.

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