Trabajar con fechas y horas

Para trabajar con fechas y horas, MySQL tiene varios tipos de datos: DATE, TIME, DATETIME y TIMESTAMP.

TipoDescripciónRango de valoresTamaño
DATEGuarda valores de fecha con el formato YYYY-MM-DD.
Por ejemplo, 2022-12-05
de 1000-01-01 a 9999-12-313 bytes
TIMEGuarda valores de hora con el formato HH:MM:SS (o HHH:MM:SS para valores con un número mayor de horas).
Por ejemplo, 800:50:50
de -838:59:59 a 838:59:593 bytes
DATETIMEGuarda la fecha y la hora con el formato YYYY-MM-DD HH:MM:SS.
Por ejemplo, 2022-12-05 10:37:22
de 1000-01-01 00:00:00 a 9999-12-31 23:59:598 bytes
TIMESTAMPGuarda la fecha y la hora con el formato YYYY-MM-DD HH:MM:SS.
Por ejemplo, 2022-12-05 10:37:22
de 1970-01-01 00:00:01 a 2038-01-19 03:14:074 bytes

Para trabajar con fechas y horas, PostgreSQL tiene varios tipos de datos: DATE, TIME, TIMESTAMP, TIMESTAMPTZ e INTERVAL.

TipoDescripciónRango de valoresTamaño
DATEGuarda valores de fecha con el formato YYYY-MM-DD.
Por ejemplo, 2022-12-05
del 4713 a. C. al 5874897 d. C.4 bytes
TIMEGuarda valores de hora con el formato HH:MM:SS.
Por ejemplo, 14:30:45
de 00:00:00 a 24:00:008 bytes
TIMESTAMPGuarda la fecha y la hora sin zona horaria.
Por ejemplo, 2022-12-05 10:37:22
del 4713 a. C. al 294276 d. C.8 bytes
TIMESTAMPTZGuarda un instante convertido a UTC.
Por ejemplo, 2022-12-05 10:37:22+03
del 4713 a. C. al 294276 d. C.8 bytes
INTERVALGuarda un intervalo de tiempo.
Por ejemplo, 1 year 2 months 3 days 4 hours
de -178.000.000 a 178.000.000 años16 bytes

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.4
CREATE 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;
datetime_field
2022-06-16 16:37:23

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.4
CREATE 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;
timestamp_field
2022-06-16 19:37:23

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.4
CREATE 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.4
CREATE 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.4
SELECT '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.4
CREATE 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;
datetime
2022-06-16 16:37:23
2022-05-31 08:15:04
2014-02-22 16:37:22
2022-06-16 16:37:23
2021-02-12 00:00:00

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.4
CREATE 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.