sql >> Base de Datos >  >> RDS >> Mysql

Campos de fecha y hora de MySQL y horario de verano:¿cómo hago referencia a la hora adicional?

Lo tengo resuelto para mis propósitos. Resumiré lo que aprendí (lo siento, estas notas son detalladas; son tanto para mi referencia futura como para cualquier otra cosa).

Al contrario de lo que dije en uno de mis comentarios anteriores, los campos DATETIME y TIMESTAMP do comportarse de manera diferente. Los campos TIMESTAMP (como indican los documentos) toman lo que les envíe en formato "YYYY-MM-DD hh:mm:ss" y lo convierten de su zona horaria actual a la hora UTC. Lo contrario sucede de manera transparente cada vez que recupera los datos. Los campos DATETIME no realizan esta conversión. Toman todo lo que les envías y lo almacenan directamente.

Ni los tipos de campo DATETIME ni TIMESTAMP pueden almacenar datos con precisión en una zona horaria que observa DST . Si almacena "2009-11-01 01:30:00", los campos no tienen forma de distinguir qué versión de la 1:30 a. m. quería:la versión -04:00 o -05:00.

Ok, entonces debemos almacenar nuestros datos en una zona horaria que no sea DST (como UTC). Los campos TIMESTAMP no pueden manejar estos datos con precisión por las razones que explicaré:si su sistema está configurado en una zona horaria DST, es posible que lo que ingresa en TIMESTAMP no sea lo que obtiene. Incluso si le envía datos que ya ha convertido a UTC, seguirá asumiendo que los datos están en su zona horaria local y realizará otra conversión a UTC. Este viaje de ida y vuelta de local a UTC impuesto por TIMESTAMP tiene pérdida cuando su zona horaria local observa DST (ya que "2009-11-01 01:30:00" se asigna a 2 horas diferentes posibles).

Con DATETIME puede almacenar sus datos en cualquier zona horaria que desee y estar seguro de que recibirá lo que envíe (no se ve obligado a realizar las conversiones de ida y vuelta con pérdidas que los campos TIMESTAMP le imponen). Entonces, la solución es usar un campo DATETIME y antes de guardar en el campo convierta la zona horaria de su sistema en cualquier zona que no sea DST en la que desee guardarlo (creo que UTC es probablemente la mejor opción). Esto le permite construir la lógica de conversión en su lenguaje de secuencias de comandos para que pueda guardar explícitamente el equivalente UTC de "2009-11-01 01:30:00 -04:00" o ""2009-11-01 01:30:00 -05:00".

Otra cosa importante a tener en cuenta es que las funciones matemáticas de fecha/hora de MySQL no funcionan correctamente alrededor de los límites de DST si almacena sus fechas en un DST TZ. Razón de más para ahorrar en UTC.

En pocas palabras, ahora hago esto:

Al recuperar los datos de la base de datos:

Interprete explícitamente los datos de la base de datos como UTC fuera de MySQL para obtener una marca de tiempo Unix precisa. Uso la función strtotime() de PHP o su clase DateTime para esto. No se puede hacer de manera confiable dentro de MySQL usando las funciones CONVERT_TZ() o UNIX_TIMESTAMP() de MySQL porque CONVERT_TZ solo generará un valor 'YYYY-MM-DD hh:mm:ss' que adolece de problemas de ambigüedad, y UNIX_TIMESTAMP() asume su la entrada está en la zona horaria del sistema, no en la zona horaria en la que REALMENTE se almacenaron los datos (UTC).

Al almacenar los datos en la base de datos:

Convierta su fecha a la hora UTC precisa que desee fuera de MySQL. Por ejemplo:con la clase DateTime de PHP, puede especificar "2009-11-01 1:30:00 EST" distintamente de "2009-11-01 1:30:00 EDT", luego convertirlo a UTC y guardar la hora UTC correcta a su campo DATETIME.

Uf. Muchas gracias por los aportes y la ayuda de todos. Esperemos que esto le ahorre a alguien más algunos dolores de cabeza en el futuro.

Por cierto, estoy viendo esto en MySQL 5.0.22 y 5.0.27