Manejar datos de fecha y hora es fundamental en casi cualquier aplicación o sistema que utilice una base de datos. Sin embargo, la forma en que estos datos se almacenan internamente (a menudo en formatos estándar como 'YYYY-MM-DD HH:MM:SS') no siempre es la más adecuada o legible para ser presentada a un usuario final, en informes o para realizar análisis específicos. Es aquí donde surge la necesidad de cambiar o adaptar el formato de estos datos temporales al recuperarlos de la base de datos.

Imagina que tienes una tabla con registros de usuarios y la fecha y hora exacta en que se registraron. Mostrar '2023-10-27 10:30:00' puede ser preciso, pero quizás prefieras algo más amigable como 'Viernes, 27 de Octubre de 2023 a las 10:30 AM'. MySQL, uno de los sistemas de gestión de bases de datos más populares, ofrece una solución elegante y potente para este desafío: la función DATE_FORMAT().

Esta función te permite tomar un valor de fecha o fecha y hora y convertirlo en una cadena de caracteres con el formato exacto que especifiques. Es una herramienta increíblemente útil para personalizar la salida de tus consultas y hacer que tus datos temporales sean más comprensibles y presentables.
- ¿Qué es DATE_FORMAT() y Cómo Funciona?
- Ejemplo Práctico: Formateando la Fecha de Registro
- Especificadores de Formato Comunes en DATE_FORMAT()
- Combinando Especificadores y Texto Literal
- Consideraciones Importantes
- Preguntas Frecuentes sobre Formato de Fechas en MySQL
- ¿Puedo usar DATE_FORMAT() para cambiar el formato en que se *almacena* la fecha?
- ¿Cómo formateo solo la fecha o solo la hora?
- ¿Cómo puedo obtener el nombre del día de la semana o del mes en español si mi servidor no está configurado para español?
- ¿Puedo usar DATE_FORMAT() en la cláusula WHERE o ORDER BY?
- Conclusión
¿Qué es DATE_FORMAT() y Cómo Funciona?
La función DATE_FORMAT() en MySQL es una de las funciones más utilizadas cuando se trabaja con datos temporales. Su propósito principal es convertir un valor de fecha o fecha y hora a una cadena de caracteres formateada según un patrón específico. Esto es crucial porque, si bien las bases de datos almacenan fechas y horas en un formato interno optimizado para almacenamiento y operaciones, a menudo necesitamos presentarlos de una manera que sea más natural para los humanos o que cumpla con requisitos de formato específicos (por ejemplo, para reportes, interfaces de usuario, etc.).
La sintaxis básica de DATE_FORMAT() es la siguiente:
DATE_FORMAT(fecha, formato)
- fecha: Este es el primer argumento y es el valor de fecha, hora, fecha y hora, o timestamp que deseas formatear. Puede ser el nombre de una columna de uno de estos tipos de datos, una expresión que retorne un valor temporal, o incluso una literal de fecha/hora.
- formato: Este es el segundo argumento y es una cadena de caracteres que define el patrón de salida deseado. Esta cadena puede contener texto literal (que se incluirá tal cual en la salida) y, lo más importante, *especificadores de formato*. Los especificadores son secuencias de caracteres que comienzan con el símbolo de porcentaje (
%) y le indican a MySQL cómo extraer y presentar diferentes partes del valor de fecha/hora (año, mes, día, hora, minuto, segundo, nombre del día de la semana, etc.).
El poder de DATE_FORMAT() reside en la gran cantidad de especificadores de formato que soporta. Al combinar estos especificadores con texto literal en la cadena de formato, puedes crear prácticamente cualquier representación de fecha y hora que puedas imaginar.
Ejemplo Práctico: Formateando la Fecha de Registro
Veamos cómo aplicar DATE_FORMAT() con un ejemplo concreto, similar al proporcionado. Supongamos que tenemos una tabla llamada student_platform con la siguiente estructura y datos:
CREATE TABLE student_platform (
id INT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
registration_datetime DATETIME
);INSERT INTO student_platform (id, first_name, last_name, registration_datetime) VALUES
(1, 'Lora', 'Lorens', '2019-02-23 12:04:23'),
(2, 'Anne', 'Smith', '2018-07-10 10:12:15'),
(3, 'Tom', 'Jackson', '2019-03-09 08:20:33'),
(4, 'Richard', 'Williams', '2018-09-30 06:07:34');
Queremos obtener el nombre, apellido y la fecha/hora de registro de cada estudiante, pero formateada de una manera específica: nombre abreviado del día de la semana, seguido de una coma, el año completo, el nombre completo del mes, el día del mes, y la hora, minutos y segundos en formato de 24 horas. El formato deseado es, por ejemplo, 'Mar, 2019 Febrero 17 11:18:55'.
Para lograr esto, utilizaremos DATE_FORMAT() en la columna registration_datetime y especificaremos la cadena de formato que corresponda al patrón deseado. Analicemos el formato deseado y los especificadores necesarios:
- 'Mar': Nombre abreviado del día de la semana ->
%a - ', ': Texto literal
- '2019': Año con 4 dígitos ->
%Y - ' ': Espacio literal
- 'Febrero': Nombre completo del mes ->
%M - ' ': Espacio literal
- '17': Día del mes (sin ceros iniciales) ->
%e - ' ': Espacio literal
- '11:18:55': Hora (00-23), minutos (00-59), segundos (00-59) ->
%H:%i:%s
Combinando estos especificadores y texto literal, la cadena de formato sería: '%a, %Y %M %e %H:%i:%s'.
La consulta SQL para obtener los datos con el formato deseado sería:
SELECT
first_name,
last_name,
DATE_FORMAT(registration_datetime, '%a, %Y %M %e %H:%i:%s') AS format_registration_datetime
FROM
student_platform;
Ejecutando esta consulta sobre los datos de ejemplo, obtendríamos un resultado similar a este:
+------------+------------+----------------------------+
| first_name | last_name | format_registration_datetime |
+------------+------------+----------------------------+
| Lora | Lorens | Sáb, 2019 Febrero 23 12:04:23 |
| Anne | Smith | Mar, 2018 Julio 10 10:12:15 |
| Tom | Jackson | Sáb, 2019 Marzo 9 08:20:33 |
| Richard | Williams | Lun, 2018 Septiembre 30 06:07:34 |
+------------+------------+----------------------------+
Como puedes ver, la columna registration_datetime, que originalmente tenía el formato estándar de MySQL, ahora se presenta con el formato personalizado que especificamos utilizando DATE_FORMAT().
Especificadores de Formato Comunes en DATE_FORMAT()
La clave para dominar DATE_FORMAT() es conocer los diferentes especificadores disponibles. Aquí te presento una tabla con algunos de los más comunes y útiles:
| Especificador | Descripción | Ejemplo de Salida (para 2023-10-27 10:30:05) |
|---|---|---|
%a | Nombre abreviado del día de la semana (Lun, Mar, etc.) | Lun |
%b | Nombre abreviado del mes (Ene, Feb, etc.) | Oct |
%c | Mes como número (1-12) | 10 |
%D | Día del mes con sufijo inglés (1st, 2nd, 3rd, ...) | 27th |
%d | Día del mes con dos dígitos (01-31) | 27 |
%e | Día del mes sin ceros iniciales (1-31) | 27 |
%f | Microsegundos (000000-999999) | 000000 (si no hay microsegundos) |
%H | Hora (00-23) | 10 |
%h | Hora (01-12) | 10 |
%I | Hora (01-12) | 10 |
%i | Minutos (00-59) | 30 |
%j | Día del año (001-366) | 300 (aprox) |
%k | Hora (0-23) | 10 |
%l | Hora (1-12) | 10 |
%M | Nombre completo del mes (Enero, Febrero, etc.) | Octubre |
%m | Mes con dos dígitos (00-12) | 10 |
%p | AM o PM | AM |
%r | Hora en formato 12 horas con AM/PM (hh:mm:ss AM/PM) | 10:30:05 AM |
%S | Segundos (00-59) | 05 |
%s | Segundos (00-59) | 05 |
%T | Hora en formato 24 horas (HH:MM:SS) | 10:30:05 |
%U | Semana del año (00-53), donde el primer domingo es el primer día de la semana 1 | 43 (aprox) |
%u | Semana del año (00-53), donde el primer lunes es el primer día de la semana 1 | 44 (aprox) |
%V | Semana del año (01-53), donde el primer domingo es el primer día de la semana 1 (usado con %X) | 43 (aprox) |
%v | Semana del año (01-53), donde el primer lunes es el primer día de la semana 1 (usado con %x) | 44 (aprox) |
%W | Nombre completo del día de la semana (Lunes, Martes, etc.) | Viernes |
%w | Día de la semana (0=Domingo, 6=Sábado) | 5 |
%X | Año para la semana (%V), donde el primer domingo es el primer día de la semana 1 | 2023 |
%x | Año para la semana (%v), donde el primer lunes es el primer día de la semana 1 | 2023 |
%Y | Año con cuatro dígitos | 2023 |
%y | Año con dos dígitos | 23 |
%% | Un literal '%' | % |
Esta tabla no es exhaustiva, pero cubre los especificadores más comunes. Puedes consultar la documentación oficial de MySQL para ver la lista completa y detalles específicos sobre el comportamiento de cada uno, especialmente aquellos relacionados con semanas y años fiscales.
Combinando Especificadores y Texto Literal
La verdadera flexibilidad de DATE_FORMAT() proviene de la capacidad de combinar estos especificadores con cualquier texto literal que desees incluir en la cadena de salida. Por ejemplo:
- Para obtener '27/10/2023':
'%d/%m/%Y' - Para obtener 'Octubre 27, 2023':
'%M %e, %Y' - Para obtener 'Viernes, 27 de Octubre de 2023':
'%W, %e de %M de %Y' - Para obtener '10:30 AM':
'%h:%i %p' - Para obtener '2023-10-27T10:30:05':
'%Y-%m-%dT%H:%i:%S'(útil para formatos ISO 8601)
Simplemente escribe la cadena de formato deseada, insertando los especificadores donde quieras que aparezca la parte correspondiente de la fecha/hora, y el texto literal donde quieras que aparezca tal cual.
Consideraciones Importantes
Al usar DATE_FORMAT(), ten en cuenta lo siguiente:
- Tipo de Retorno: La función siempre retorna una cadena de caracteres (STRING). Esto significa que el resultado no es un tipo de dato temporal con el que puedas realizar cálculos de fecha/hora directamente (aunque puedes convertirlo de nuevo si es necesario). El objetivo es la presentación.
- Localización: Los nombres de días y meses (usando
%a,%W,%b,%M) dependen de la configuración de idioma del servidor MySQL (variablelc_time_names). Si tu servidor está configurado para español, obtendrás 'Lunes', 'Enero', etc. Si está en inglés, obtendrás 'Monday', 'January', etc. Asegúrate de que la configuración del servidor o de la sesión sea la correcta para obtener los nombres en el idioma deseado. - Valores Nulos: Si el valor de fecha/hora de entrada es
NULL,DATE_FORMAT()también retornaráNULL. - Rendimiento: Aplicar funciones a columnas en la cláusula
WHEREpuede afectar el rendimiento de las consultas, ya que puede impedir el uso de índices en esa columna.DATE_FORMAT()no es una excepción. Si necesitas filtrar por un rango de fechas, es mejor hacerlo directamente sobre la columna temporal sin formatear.DATE_FORMAT()es ideal para la cláusulaSELECT(para presentación) o para filtrar si la función se aplica a un literal o variable, no a la columna indexada.
Preguntas Frecuentes sobre Formato de Fechas en MySQL
¿Puedo usar DATE_FORMAT() para cambiar el formato en que se *almacena* la fecha?
No. DATE_FORMAT() solo cambia la *representación* de la fecha/hora cuando la recuperas con un SELECT. La forma en que los datos se almacenan en la tabla (en columnas de tipo DATE, TIME, DATETIME, TIMESTAMP) sigue siendo el formato interno de MySQL. Para cambiar el formato de almacenamiento, tendrías que modificar el tipo de dato de la columna (lo cual generalmente no se recomienda a menos que haya una razón muy específica y sepas las implicaciones) o almacenar la fecha como una cadena de caracteres (lo cual tampoco se recomienda, ya que pierdes las funcionalidades temporales nativas de MySQL).
¿Cómo formateo solo la fecha o solo la hora?
Puedes usar DATE_FORMAT() tanto con valores de tipo DATE (solo fecha) como TIME (solo hora), así como con DATETIME y TIMESTAMP. Si tu columna es DATE, los especificadores de hora simplemente retornarán ceros o valores vacíos. Si es TIME, los especificadores de fecha harán lo mismo. Si es DATETIME o TIMESTAMP, puedes usar cualquier combinación de especificadores de fecha y hora.
Por ejemplo, para obtener solo la fecha formateada de una columna DATETIME:
SELECT DATE_FORMAT(registration_datetime, '%d/%m/%Y') AS solo_fecha FROM student_platform;
Para obtener solo la hora formateada:
SELECT DATE_FORMAT(registration_datetime, '%H:%i:%S') AS solo_hora FROM student_platform;
¿Cómo puedo obtener el nombre del día de la semana o del mes en español si mi servidor no está configurado para español?
Si no puedes cambiar la configuración global o de sesión de lc_time_names en el servidor, puedes lograr esto manualmente utilizando funciones condicionales como CASE junto con funciones que extraen partes de la fecha, como DAYOFWEEK() o MONTH(). Sin embargo, esto es mucho más verboso y menos eficiente que usar DATE_FORMAT() con la localización correcta.
Ejemplo (para el día de la semana, menos eficiente):
SELECT CASE DAYOFWEEK(registration_datetime)
WHEN 1 THEN 'Domingo'
WHEN 2 THEN 'Lunes'
WHEN 3 THEN 'Martes'
WHEN 4 THEN 'Miércoles'
WHEN 5 THEN 'Jueves'
WHEN 6 THEN 'Viernes'
WHEN 7 THEN 'Sábado'
END AS dia_semana_espanol
FROM student_platform;
Lo ideal es asegurar que la configuración de localización de tiempo en tu servidor MySQL sea la adecuada.
¿Puedo usar DATE_FORMAT() en la cláusula WHERE o ORDER BY?
Técnicamente sí puedes, pero no es recomendable en la mayoría de los casos, especialmente en tablas grandes o si la columna está indexada. Cuando usas DATE_FORMAT(columna, ...) en la cláusula WHERE o ORDER BY, MySQL a menudo no puede utilizar un índice existente en la columna, lo que resulta en un escaneo completo de la tabla (full table scan) y un rendimiento mucho más lento.
Si necesitas filtrar o ordenar por fecha/hora, hazlo directamente sobre la columna sin formatear. Por ejemplo, en lugar de:
SELECT ... FROM tabla WHERE DATE_FORMAT(columna_fecha, '%Y-%m-%d') = '2023-10-27'; -- MAL para rendimiento
Usa:
SELECT ... FROM tabla WHERE columna_fecha >= '2023-10-27' AND columna_fecha < '2023-10-28'; -- BIEN para rendimiento
O para ordenar:
SELECT DATE_FORMAT(columna_fecha, '%d/%m/%Y') AS fecha_formato FROM tabla ORDER BY columna_fecha; -- BIEN, ordena por el valor original, pero muestra el formato
Esto ordena correctamente por la secuencia cronológica de las fechas, no por la cadena de caracteres formateada.
Conclusión
La función DATE_FORMAT() es una herramienta esencial en el arsenal de cualquier desarrollador o administrador de bases de datos que trabaje con MySQL. Permite transformar fácilmente la representación de datos de fecha y hora para adaptarlos a las necesidades de presentación, informes o integración con otras aplicaciones. Al comprender su sintaxis, los diversos especificadores de formato disponibles y las consideraciones de rendimiento, puedes utilizar esta función de manera efectiva para hacer que tus datos temporales sean mucho más legibles y útiles. Recuerda siempre usarla principalmente para la salida de tus consultas (en la cláusula SELECT) y evitar su uso en WHERE o ORDER BY sobre columnas indexadas para mantener un buen rendimiento.
Si quieres conocer otros artículos parecidos a Formatear Fechas y Horas en MySQL puedes visitar la categoría Bases de datos.

Aprende mas sobre MySQL