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

Cómo manejar la zona horaria de MySQL en el script

Ejecutaste esta consulta de diagnóstico de tiempo en tu servidor MySQL.

select @@time_zone, now(), utc_timestamp()

Está claro a partir de su hora local y hora utc que la configuración de zona horaria del sistema de su máquina servidor es 'Canadá/Montaña', y el software del servidor MySQL no tiene su propia configuración de zona horaria.

Si recoge sus tablas y las mueve sin cambios a un servidor en alguna zona horaria cercana, puede actualizar su software siempre para emitir el comando

set time_zone = 'Canada/Mountain';

justo después de conectarse desde su software. Esto hará que su nueva conexión MySQL se comporte como la actual en cuanto a la zona horaria. Si posee el servidor MySQL, puede establecer su zona horaria predeterminada de acuerdo con las instrucciones de esta página. http://dev.mysql.com/doc /refman/5.5/en/time-zone-support.html

Ahora, aquí está la historia sobre los tipos de datos de tiempo. DATE , TIME y DATETIME son todos ignorantes de la zona horaria . Una vez que haya almacenado un valor de fecha/hora, recuperará el mismo valor incluso si cambia la configuración de su zona horaria.

El TIMESTAMP el tipo de datos es sensible a la zona horaria . Esos elementos de datos siempre se almacenan en UTC, también conocido como Z, time , anteriormente conocida como hora media de Greenwich. Siempre se convierten a UTC cuando se almacenan y siempre se vuelven a convertir cuando se recuperan.

Las funciones integradas para obtener la fecha y hora actuales (NOW() y amigos) son sensibles a la zona horaria . Darán valores en la hora local. Las excepciones son las tres funciones que comienzan con UTC_ que arrojan valores en tiempo UTC.

Muchas aplicaciones de múltiples zonas horarias de MySQL utilizan la siguiente disciplina operativa:

  1. Pregunte a cada usuario por una zona horaria de preferencia del usuario, o descúbralo a partir de algún otro dato personal sobre el usuario. (Los teléfonos tienen esta información provista desde la red). Guárdala como un zoneinfo-friendly descriptor de zona horaria ('América/Nueva_York', 'Canadá/Montaña', 'Europa/Viena', etc.) en nombre del usuario.
  2. Al establecer una sesión de MySQL en nombre del usuario, establezca la zona horaria del usuario con un set time_zone consulta como la que se muestra arriba. Deberías hacer esto justo después de tu connect operación.
  3. Almacenar las fechas y horas de los usuarios en TIMESTAMP tipos de datos. Se convertirán a UTC a medida que se almacenen.
  4. Recupéralas según sea necesario. Se volverán a convertir a la hora local.

La idea es que la zona horaria de su usuario sea parte de su contexto. Esto funciona bien, porque si el usuario A está en Vancouver y el usuario B en Halifax, y por alguna razón el usuario B ve los datos de tiempo del usuario A, se le mostrarán a B en el horario del Atlántico más o menos automáticamente.

También es bueno porque trata de manera transparente con los caprichos globales del cambio de la hora diurna a la estándar. Se mostrará una marca de tiempo del verano pasado en la hora local del verano pasado.

Muchos administradores de servidores para uso global establecen la hora del servidor del sistema, o la zona horaria predeterminada de MySQL, en UTC. (El tuyo no).

Otra forma de manejar todo esto es la forma en que ha comenzado. Elija una zona horaria y almacene sus marcas de tiempo con respecto a esa zona horaria. Es mejor si elige una zona horaria que no alterne entre la luz del día y la hora estándar en ese caso. Luego, cuando almacene tiempos en la base de datos, convierta explícitamente. Almacenarías los tiempos de los usuarios en Ottawa haciendo algo como esto.

INSERT INTO tbl (appt) VALUES ( 'whatever-time' - INTERVAL 120 MINUTE)

y obtendrías los valores de la misma manera. Esto es propenso a errores, pero puede hacer que funcione.

Finalmente, puede realizar sus conversiones usted mismo. Si desea saber cuántos minutos de diferencia hay entre una zona horaria arbitraria y UTC, pruebe estas dos consultas.

set time_zone = 'Canada/Atlantic';
select timestampdiff(minute, utc_timestamp(), now());

En esta época del año eso devuelve -240, que es -4:00. Debe usar minutos en lugar de horas debido a las diferencias de zona horaria de media hora o cuarto de hora en algunos países.

Por último, cuidado. TIMESTAMP los tipos de datos no representan tiempos anteriores a 1970. Y, en mi instancia de MariaDB 10.0, parece ir al infierno justo después de 2038-01-19T03:14:07 UTC cuando el tiempo pasa de 32 bits.