Trabajar con fechas y horas
Para trabajar con fechas y horas, MySQL tiene varios tipos de datos: DATE, TIME, DATETIME y TIMESTAMP.
Para trabajar con fechas y horas, PostgreSQL tiene varios tipos de datos: DATE, TIME, TIMESTAMP, TIMESTAMPTZ e INTERVAL.
Diferencia entre TIMESTAMP y DATETIME
En MySQL, los tipos de datos DATETIME y TIMESTAMP se parecen mucho, ya que los dos sirven para guardar fecha y hora. Pero entre ellos hay varias diferencias importantes que determinan cuál conviene usar en cada caso.
DATETIME
Guarda valores en el rango de 1000-01-01 00:00:00 a 9999-12-31 23:59:59 y ocupa 8 bytes. Este tipo de datos no depende de la zona horaria configurada en MySQL. Siempre se muestra exactamente tal y como se estableció y como se guarda en la base de datos. Es decir, si cambia la zona horaria, la hora que se muestra no cambia.
MySQL 8.4CREATE TABLE datetime_table (datetime_field DATETIME); SET @@session.time_zone="+00:00"; -- restablecemos la zona horaria en MySQL INSERT INTO datetime_table VALUES("2022-06-16 16:37:23"); SET @@session.time_zone="+03:00"; -- cambiamos la zona horaria en MySQL SELECT * FROM datetime_table;
TIMESTAMP
Guarda cuántos segundos han pasado desde 1970-01-01 00:00:00 en la zona horaria UTC y ocupa 4 bytes. Al consultarlo, se muestra teniendo en cuenta la zona horaria actual. La zona horaria se puede configurar en el sistema operativo en el que funciona MySQL, en los ajustes globales de MySQL o en una sesión concreta. Al crear un registro con el tipo TIMESTAMP, el valor se guarda en la base de datos en UTC.
MySQL 8.4CREATE TABLE timestamp_table (timestamp_field TIMESTAMP); SET @@session.time_zone="+00:00"; -- restablecemos la zona horaria en MySQL INSERT INTO timestamp_table VALUES("2022-06-16 16:37:23"); SET @@session.time_zone="+03:00"; -- cambiamos la zona horaria en MySQL SELECT * FROM timestamp_table;
Ten también en cuenta que TIMESTAMP solo admite valores de 1970-01-01 00:00:01 a 2038-01-19 03:14:07, lo que limita su uso. Por ejemplo, este tipo de datos no sirve para guardar las fechas de nacimiento de los usuarios.
Diferencia entre TIMESTAMP y TIMESTAMPTZ
En PostgreSQL hay dos tipos principales para guardar fecha y hora: TIMESTAMP (sin zona horaria) y TIMESTAMPTZ (con zona horaria).
TIMESTAMP
El tipo TIMESTAMP (o TIMESTAMP WITHOUT TIME ZONE) guarda la fecha y la hora sin información sobre la zona horaria. Esto significa que PostgreSQL no sabe en qué zona horaria se registró la fecha y no hace ninguna conversión.
MySQL 8.4CREATE TABLE timestamp_table (timestamp_field TIMESTAMP); SET timezone = 'UTC'; -- establecemos la zona horaria UTC INSERT INTO timestamp_table VALUES('2022-06-16 16:37:23'); SET timezone = 'Europe/Moscow'; -- cambiamos la zona horaria SELECT * FROM timestamp_table;
Resultado: 2022-06-16 16:37:23 (el valor no ha cambiado)
TIMESTAMPTZ
El tipo TIMESTAMPTZ (o TIMESTAMP WITH TIME ZONE) guarda la fecha y la hora teniendo en cuenta la zona horaria, pero no guarda la zona horaria en sí. PostgreSQL convierte automáticamente la hora a UTC para guardarla y, al mostrarla, la vuelve a convertir a la zona horaria de la sesión actual.
MySQL 8.4CREATE TABLE timestamptz_table (timestamptz_field TIMESTAMPTZ); SET timezone = 'UTC'; -- establecemos la zona horaria UTC INSERT INTO timestamptz_table VALUES('2022-06-16 16:37:23'); SET timezone = 'Europe/Moscow'; -- cambiamos la zona horaria a Moscú (+3) SELECT * FROM timestamptz_table;
Resultado: 2022-06-16 19:37:23+03 (la hora se ha ajustado automáticamente)
INTERVAL
El tipo INTERVAL se usa para guardar periodos de tiempo. Puede representar intervalos en años, meses, días, horas, minutos y segundos.
MySQL 8.4SELECT '1 year 2 months 3 days 4 hours 5 minutes 6 seconds'::INTERVAL; SELECT '2 weeks'::INTERVAL; SELECT '90 minutes'::INTERVAL;
Cómo indicar los valores
Los valores DATETIME, DATE y TIMESTAMP se pueden indicar de una de estas formas:
- Como cadena con el formato YYYY-MM-DD HH:MM:SS o YY-MM-DD HH:MM:SS para indicar fecha y hora
- Como cadena con el formato YYYY-MM-DD o YY-MM-DD para indicar solo la fecha
Al escribir una fecha, puedes usar cualquier signo de puntuación como separador entre las partes de la fecha o de la hora. También puedes escribir la fecha sin ningún separador, todo junto.
MySQL 8.4CREATE TABLE date_table (datetime TIMESTAMP); INSERT INTO date_table VALUES("2022-06-16 16:37:23"); INSERT INTO date_table VALUES("22.05.31 8+15+04"); INSERT INTO date_table VALUES("2014/02/22 16*37*22"); INSERT INTO date_table VALUES("20220616163723"); INSERT INTO date_table VALUES("2021-02-12"); SELECT * FROM date_table;
Los valores de los tipos de fecha y hora se pueden indicar en distintos formatos:
- Como cadena con el formato ISO 8601: 'YYYY-MM-DD HH:MM:SS'
- Como cadena con zona horaria: 'YYYY-MM-DD HH:MM:SS+TZ'
- Solo la fecha: 'YYYY-MM-DD'
- Solo la hora: 'HH:MM:SS'
MySQL 8.4CREATE TABLE date_table ( date_field DATE, time_field TIME, timestamp_field TIMESTAMP, timestamptz_field TIMESTAMPTZ ); INSERT INTO date_table VALUES( '2022-06-16', '16:37:23', '2022-06-16 16:37:23', '2022-06-16 16:37:23+03' ); SELECT * FROM date_table;
PostgreSQL entiende también otros formatos de fecha, pero el más fiable es ISO 8601: se interpreta de forma inequívoca con cualquier configuración.