php - date_default_timezone_set - Cómo almacenar fechas de repetición teniendo en cuenta el horario de verano
php timezone (1)
Primero, reconozca que en la terminología moderna debe decir UTC en lugar de GMT. En su mayoría son equivalentes, excepto que UTC se define con mayor precisión. Reserve el término GMT para referirse a la parte de la zona horaria en el Reino Unido que está vigente durante los meses de invierno con el desplazamiento UTC + 0.
Ahora a tu pregunta. UTC no es necesariamente la mejor manera de almacenar todos los valores de fecha y hora. Funciona especialmente bien para eventos pasados , o para futuros eventos absolutos , pero no funciona tan bien para futuros eventos locales , especialmente futuros eventos recurrentes .
Recientemente escribí sobre esto en otra respuesta , y es uno de los pocos casos excepcionales en que la hora local tiene más sentido que UTC. El argumento principal es el "problema del despertador". Si configura su reloj despertador por UTC, se despertará una hora más temprano o más tarde el día de las transiciones DST. Esta es la razón por la cual la mayoría de las personas configuran sus despertadores por hora local.
Por supuesto, no puede simplemente almacenar una hora local si está trabajando con datos de todo el mundo. Debe almacenar algunas cosas diferentes:
- La hora local del evento recurrente, como "08:00"
- El huso horario en el que se expresa la hora local, como "America / New_York"
- El patrón de recurrencia, en cualquier formato, tiene sentido para su aplicación, como diaria, quincenal o el tercer jueves del mes, etc.
- El próximo UTC inmediato de fecha y hora, lo mejor que puede proyectarlo.
- Tal vez, pero no siempre, una lista de fechas y horas de eventos futuros UTC, proyecta un período predefinido en el futuro (tal vez una semana, tal vez 6 meses, tal vez uno o dos años, dependiendo de sus necesidades).
Para los dos últimos, entienda que el equivalente UTC de cualquier fecha / hora local puede cambiar si el gobierno responsable de esa zona horaria decide cambiar algo. Como hay varias actualizaciones de bases de datos de zonas horarias cada año, le conviene tener un plan para suscribirse a anuncios de actualizaciones y actualizar su base de datos de zona horaria regularmente. Cada vez que actualice los datos de la zona horaria, deberá volver a calcular los tiempos UTC equivalentes de todos los eventos futuros.
Tener los equivalentes UTC es importante si planea mostrar cualquier tipo de lista de eventos que abarque más de una zona horaria. Esos son los valores que consultará para compilar esa lista.
Otro punto a considerar es que si un evento está programado para una hora local que ocurre durante una transición DST hacia atrás, tendrá que decidir si el evento ocurre en la primera instancia (generalmente) o en la segunda instancia (a veces), o ambos (raramente), e incorporan a su aplicación un mecanismo para garantizar que el evento no se active dos veces a menos que así lo desee.
Si estabas buscando una respuesta simple, lo siento, pero no hay una. Programar eventos futuros a través de zonas horarias es una tarea complicada.
Enfoque alternativo
Algunas personas me han mostrado una técnica en la que usan la hora UTC para la programación, que es que eligen una fecha de inicio en la hora local, la convierten a UTC para que se almacene y también almacenan la identificación de la zona horaria. Luego, en tiempo de ejecución, aplican la zona horaria para convertir la hora UTC original a la hora local, luego usan esa hora local para calcular las otras recurrencias, como si fuera la almacenada originalmente como se indicó anteriormente.
Si bien esta técnica funcionará , los inconvenientes son:
Si hay una actualización de zona horaria que cambia la hora local antes de que se ejecute la primera instancia, se descartará todo el cronograma. Esto puede mitigarse eligiendo un momento en el pasado para la "primera" instancia, de modo que la segunda instancia sea realmente la primera.
Si el tiempo es realmente un "tiempo flotante" que debería seguir al usuario (como en una alarma de reloj en un teléfono celular), igual tendría que almacenar información de zona horaria para la zona en la que se creó originalmente, incluso si esa no es la zona en la que quieres correr
Agrega complejidad adicional sin ningún beneficio. Me reservaría esta técnica para situaciones en las que haya tenido un programador solo de UTC en el que esté intentando adaptar el soporte de zona horaria.
Estoy almacenando eventos en mi base de datos. Tengo fechas de ''inicio'' y ''fin'', ''tickets_start'' y ''tickets_end'' (para cuando la venta de entradas realmente comienza / finaliza, en lugar del inicio / fin del evento real).
Hasta ahora, he creado métodos que hacen todas las cosas divertidas, como convertir la fecha / horas en GMT antes de guardar, y luego volver a su zona horaria respectiva para visualizar.
Estoy almacenando la zona horaria en un campo varchar con valores como "America / New_York".
Pero, ahora necesito comenzar a tratar si el usuario quiere permitir la repetición de eventos. Lo he hecho antes, y no es un gran problema, pero nunca a través de múltiples zonas horarias.
Al principio, pensé que no sería gran cosa, pero luego me di cuenta de que, si la fecha de inicio inicial era julio (como ejemplo), y se repite cada mes durante un año, en algún momento, el horario de verano lo hará para que la conversión de GMT cambie una hora de manera diferente. Un mes, al convertir 12:00, lo cambiaría a -5, y al siguiente, lo cambiaría a -4 debido a DST.
Mi idea actual es que almacenaré una minúscula ''dst'' (1) para saber si las fechas de inicio / finalización se ingresaron durante el horario de verano, y luego haré un método para modificar el tiempo por una hora si / cuando sea necesario.
Pero ... supuse que preguntaría aquí con la esperanza de que tal vez haya algo "normal" en esto o algo fácil en lo que no estoy pensando.
(cakephp 2.4.x)