Parece que no importa qué zona horaria esté en el servidor siempre y cuando tenga la hora establecida correctamente para la zona horaria actual, conozca la zona horaria de las columnas de fecha y hora que almacena y esté al tanto de los problemas con el horario de verano.
Por otro lado, si tiene el control de las zonas horarias de los servidores con los que trabaja, puede tener todo configurado en UTC internamente y nunca preocuparse por las zonas horarias y el horario de verano.
Aquí hay algunas notas que recopilé sobre cómo trabajar con zonas horarias como una forma de hoja de referencia para mí y para otros que podrían influir en la zona horaria que la persona elegirá para su servidor y cómo almacenará la fecha y la hora.
Hoja de referencia de zona horaria MySQL
Notas:
- Cambiar la zona horaria no cambiará la fecha y hora o la marca de tiempo almacenadas , pero seleccionará una fecha y hora diferente de las columnas de la marca de tiempo
- ¡Advertencia! UTC tiene segundos intermedios, estos se ven como '2012-06-30 23:59:60' y se pueden agregar al azar, con 6 meses de anticipación, debido a la desaceleración de la rotación de la tierra
GMT confunde segundos, por eso se inventó UTC.
¡Advertencia! diferentes zonas horarias regionales pueden producir el mismo valor de fecha y hora debido al horario de verano
- La columna de fecha y hora solo admite fechas 1970-01-01 00:00:01 a 2038-01-19 03:14:07 UTC, debido a una limitación .
Internamente, una columna de marca de tiempo de MySQL se almacena como UTC, pero al seleccionar una fecha, MySQL la convertirá automáticamente a la zona horaria de la sesión actual.
Al almacenar una fecha en una marca de tiempo, MySQL asumirá que la fecha está en la zona horaria de la sesión actual y la convertirá a UTC para su almacenamiento.
- MySQL puede almacenar fechas parciales en columnas de fecha y hora, como "2013-00-00 04:00:00"
- MySQL almacena "0000-00-00 00:00:00" si configura una columna de fecha y hora como NULL, a menos que establezca específicamente la columna para permitir null cuando la cree.
- Lee esto
Para seleccionar una columna de marca de tiempo en formato UTC
No importa en qué zona horaria se encuentre la sesión MySQL actual:
SELECT
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
También puede establecer el servidor o la zona horaria de sesión global o actual en UTC y luego seleccionar la marca de tiempo de esta manera:
SELECT `timestamp_field` FROM `table_name`
Para seleccionar la fecha y hora actual en UTC:
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');
Resultado de ejemplo: 2015-03-24 17:02:41
Para seleccionar la fecha y hora actual en la zona horaria de la sesión
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();
Para seleccionar la zona horaria que se configuró cuando se inició el servidor
SELECT @@system_time_zone;
Devuelve "MSK" o "+04: 00" para la hora de Moscú, por ejemplo, hay (o hubo) un error de MySQL donde, si se configura en un desplazamiento numérico, no se ajustaría el horario de verano
Para obtener la zona horaria actual
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
Volverá a las 02:00:00 si su zona horaria es +2: 00.
Para obtener la marca de tiempo UNIX actual (en segundos):
SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();
Para obtener la columna de marca de tiempo como marca de tiempo UNIX
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
Para obtener una columna de fecha y hora UTC como marca de tiempo UNIX
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
Obtenga una fecha y hora de zona horaria actual de un entero de marca de tiempo de UNIX positivo
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
Obtenga una fecha y hora UTC de una marca de tiempo UNIX
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00')
FROM `table_name`
Obtenga una fecha y hora de zona horaria actual a partir de un entero de marca de tiempo UNIX negativo
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
Hay 3 lugares donde se puede establecer la zona horaria en MySQL:
Nota: una zona horaria se puede configurar en 2 formatos:
- un desplazamiento desde UTC: '+00: 00', '+10: 00' o '-6: 00'
- como zona horaria con nombre: 'Europa / Helsinki', 'EE. UU. / Este' o 'MET'
Las zonas horarias con nombre solo se pueden usar si las tablas de información de zona horaria en la base de datos mysql se han creado y completado.
en el archivo "my.cnf"
default_time_zone='+00:00'
o
timezone='UTC'
@@ global.time_zone variable
Para ver en qué valor están configurados
SELECT @@global.time_zone;
Para establecer un valor, use cualquiera de los dos:
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';
@@ session.time_zone variable
SELECT @@session.time_zone;
Para configurarlo, use cualquiera de los dos:
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";
tanto "@@ global.time_zone variable" como "@@ session.time_zone variable" podrían devolver "SYSTEM", lo que significa que usan la zona horaria establecida en "my.cnf".
Para que los nombres de zonas horarias funcionen (incluso para la zona horaria predeterminada), debe configurar las tablas de información de zonas horarias que deben rellenarse: http://dev.mysql.com/doc/refman/5.1/en/time-zone-support. html
Nota: no puede hacer esto ya que devolverá NULL:
SELECT
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime`
FROM `table_name`
Configurar tablas de zona horaria mysql
Para CONVERT_TZ
trabajar, necesita que se llenen las tablas de zonas horarias
SELECT * FROM mysql.`time_zone` ;
SELECT * FROM mysql.`time_zone_leap_second` ;
SELECT * FROM mysql.`time_zone_name` ;
SELECT * FROM mysql.`time_zone_transition` ;
SELECT * FROM mysql.`time_zone_transition_type` ;
Si están vacíos, complételos ejecutando este comando
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
si este comando le da el error " datos demasiado largos para la columna 'abreviatura' en la fila 1 ", entonces podría ser causado por un carácter NULO al final de la abreviatura de la zona horaria
la solución es ejecutar esto
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
(if the above gives error "data too long for column 'abbreviation' at row 1")
mysql_tzinfo_to_sql /usr/share/zoneinfo > /tmp/zut.sql
echo "SET SESSION SQL_MODE = '';" > /tmp/mysql_tzinfo_to.sql
cat /tmp/zut.sql >> /tmp/mysql_tzinfo_to.sql
mysql --defaults-file=/etc/mysql/my.cnf --user=verifiedscratch -p mysql < /tmp/mysql_tzinfo_to.sql
(asegúrese de que las reglas dst de sus servidores estén actualizadas zdump -v Europe/Moscow | grep 2011
https://chrisjean.com/updating-daylight-saving-time-on-linux/ )
Vea el historial completo de transición DST (horario de verano) para cada zona horaria
SELECT
tzn.Name AS tz_name,
tztt.Abbreviation AS tz_abbr,
tztt.Is_DST AS is_dst,
tztt.`Offset` AS `offset`,
DATE_ADD('1970-01-01 00:00:00',INTERVAL tzt.Transition_time SECOND) AS transition_date
FROM mysql.`time_zone_transition` tzt
INNER JOIN mysql.`time_zone_transition_type` tztt USING(Time_zone_id, Transition_type_id)
INNER JOIN mysql.`time_zone_name` tzn USING(Time_zone_id)
-- WHERE tzn.Name LIKE 'Europe/Moscow' -- Moscow has weird DST changes
ORDER BY tzt.Transition_time ASC
CONVERT_TZ
también aplica los cambios de horario de verano necesarios según las reglas de las tablas anteriores y la fecha que utiliza.
Nota:
Según los documentos , el valor que establezca para time_zone no cambia, si lo configura como "+01: 00", por ejemplo, time_zone se establecerá como un desplazamiento de UTC, que no sigue DST, por lo que Se mantendrá igual durante todo el año.
Solo las zonas horarias nombradas cambiarán el horario durante el horario de verano.
Las abreviaturas como CET
siempre serán en invierno y en CEST
verano, mientras que +01: 00 siempre serán en UTC
hora + 1 hora y ambas no cambiarán con el horario de verano.
La system
zona horaria será la zona horaria de la máquina host donde está instalado mysql (a menos que mysql no pueda determinarlo)
Puede leer más sobre trabajar con DST aquí
preguntas relacionadas:
Fuentes: