UTC_DATE

La función UTC_DATE devuelve la fecha actual según el estándar UTC (Tiempo Universal Coordinado), sin importar la zona horaria configurada en el servidor o la sesión de MySQL. Mientras que CURDATE devuelve la fecha basada en la zona horaria de la sesión, UTC_DATE siempre refleja la fecha en el meridiano de Greenwich, lo que la convierte en una herramienta fundamental para aplicaciones que operan en múltiples países o regiones.

UTC es el estándar internacional de referencia horaria. A diferencia de las zonas horarias locales, UTC no cambia con el horario de verano ni varía según la ubicación geográfica. Cuando almacenas fechas en UTC, garantizas que todos los registros son comparables entre sí sin ambigüedad, independientemente de dónde se encuentre el usuario que los consulta.

Sintaxis

UTC_DATE
UTC_DATE()

La función no recibe argumentos. Puedes invocarla con o sin paréntesis y el resultado es idéntico. Devuelve un valor de tipo DATE en formato YYYY-MM-DD cuando se usa en un contexto de cadena, o como número YYYYMMDD cuando se usa en un contexto numérico.

Comportamiento básico

La forma más directa de usar UTC_DATE es en una consulta SELECT simple para conocer la fecha UTC actual.

SELECT UTC_DATE() AS fecha_utc, CURDATE() AS fecha_local;
fecha_utcfecha_local
2026-02-142026-02-14

Si tu servidor está configurado en una zona horaria como America/Mexico_City (UTC-6) y ejecutas esta consulta a las 11:30 PM hora local, verás una diferencia notable.

SET time_zone = 'America/Mexico_City';
SELECT UTC_DATE() AS fecha_utc, CURDATE() AS fecha_local;
fecha_utcfecha_local
2026-02-152026-02-14

En este caso, mientras en Ciudad de México todavía es 14 de febrero, en UTC ya es 15 de febrero. Esta diferencia puede ser crítica para registros contables, auditorías y cualquier sistema donde la fecha exacta importa.

Contexto numérico

Cuando UTC_DATE se utiliza en operaciones aritméticas, MySQL la convierte automáticamente al formato numérico.

SELECT UTC_DATE() + 0 AS fecha_numerica;
fecha_numerica
20260214

Este comportamiento es útil para comparaciones rápidas o para generar identificadores basados en la fecha.

SELECT CONCAT('RPT-', UTC_DATE() + 0) AS codigo_reporte;
codigo_reporte
RPT-20260214

Caso práctico: registro de eventos globales

Considera una plataforma de comercio electrónico que opera en varios países. Cada pedido debe registrar la fecha en UTC para que los reportes financieros sean consistentes, sin importar desde qué país se realizó la compra.

CREATE TABLE pedidos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    cliente_id INT NOT NULL,
    total DECIMAL(10,2) NOT NULL,
    fecha_utc DATE DEFAULT (UTC_DATE()),
    created_at DATETIME DEFAULT (UTC_TIMESTAMP())
);
 
INSERT INTO pedidos (cliente_id, total)
VALUES (1042, 259.90), (2087, 1450.00), (553, 89.50);
 
SELECT id, cliente_id, total, fecha_utc
FROM pedidos;
idcliente_idtotalfecha_utc
11042259.902026-02-14
220871450.002026-02-14
355389.502026-02-14

Al usar UTC_DATE() como valor por defecto en la columna, cada registro se marca automáticamente con la fecha UTC del momento de inserción, eliminando la dependencia de la configuración del servidor.

Caso práctico: comparar actividad entre zonas horarias

Un sistema de soporte técnico con agentes en Madrid, Buenos Aires y Bogotá necesita generar un reporte diario basado en la fecha UTC para evitar que los tickets se cuenten doble o se omitan al cruzar medianoche en diferentes zonas.

SELECT
    t.id,
    t.asunto,
    t.fecha_creacion_utc,
    a.nombre AS agente,
    a.zona_horaria
FROM tickets t
JOIN agentes a ON t.agente_id = a.id
WHERE t.fecha_creacion_utc = UTC_DATE()
ORDER BY t.fecha_creacion_utc;
idasuntofecha_creacion_utcagentezona_horaria
891Error en facturación2026-02-14Ana MartínezEurope/Madrid
892Problema con envío2026-02-14Carlos RuizAmerica/Bogota
893Solicitud de reembolso2026-02-14Laura GómezAmerica/Argentina/Buenos_Aires

De esta forma, el reporte del día siempre incluye exactamente 24 horas de actividad sin solapamientos ni huecos.

Caso práctico: vencimiento de promociones

Para una tienda online que lanza promociones con fecha de vencimiento global, usar UTC_DATE asegura que la promoción expire al mismo momento para todos los usuarios, sin importar su ubicación.

SELECT
    codigo,
    descripcion,
    descuento_porcentaje,
    fecha_inicio_utc,
    fecha_fin_utc,
    CASE
        WHEN UTC_DATE() < fecha_inicio_utc THEN 'Próximamente'
        WHEN UTC_DATE() BETWEEN fecha_inicio_utc AND fecha_fin_utc THEN 'Activa'
        ELSE 'Expirada'
    END AS estado
FROM promociones
ORDER BY fecha_inicio_utc;
codigodescripciondescuento_porcentajefecha_inicio_utcfecha_fin_utcestado
WINTER25Rebajas de invierno252026-01-152026-02-10Expirada
VALENTIN15San Valentín152026-02-102026-02-15Activa
SPRING20Primavera 2026202026-03-012026-03-31Próximamente

Manejo de NULL

UTC_DATE nunca devuelve NULL por sí misma, ya que simplemente consulta el reloj del sistema. Sin embargo, al combinarla con columnas que pueden contener valores nulos, debes tener precaución.

SELECT
    nombre,
    fecha_nacimiento,
    DATEDIFF(UTC_DATE(), fecha_nacimiento) / 365.25 AS edad_aproximada
FROM clientes
WHERE fecha_nacimiento IS NOT NULL
LIMIT 3;
nombrefecha_nacimientoedad_aproximada
María García1990-06-1535.67
Carlos López1985-11-2240.23
Laura Sánchez1998-03-0827.94

Si fecha_nacimiento fuese NULL, la expresión DATEDIFF devolvería NULL. Por ello el filtro WHERE fecha_nacimiento IS NOT NULL es importante para evitar resultados inesperados.

Combinación con otras funciones

UTC_DATE se complementa con muchas funciones de fecha. Puedes usarla con DATE_ADD para calcular fechas futuras en UTC, o con DATEDIFF para medir intervalos desde una referencia universal.

SELECT
    UTC_DATE() AS hoy_utc,
    DATE_ADD(UTC_DATE(), INTERVAL 30 DAY) AS en_30_dias_utc,
    DATE_ADD(UTC_DATE(), INTERVAL 1 YEAR) AS proximo_anio_utc;
hoy_utcen_30_dias_utcproximo_anio_utc
2026-02-142026-03-162027-02-14

También resulta útil combinarla con DAYNAME o DAYOFWEEK para determinar el día de la semana en UTC.

SELECT
    UTC_DATE() AS fecha_utc,
    DAYNAME(UTC_DATE()) AS dia_semana_utc,
    WEEK(UTC_DATE()) AS semana_del_anio;
fecha_utcdia_semana_utcsemana_del_anio
2026-02-14Saturday6

Recuerda que DAYNAME devuelve el nombre en inglés a menos que cambies la variable lc_time_names de la sesión.

En el siguiente artículo veremos UTC_TIME para obtener la hora actual en UTC.

Escrito por Eduardo Lázaro