[PHP] Fechas en Español

Mostrar fechas en español con PHP

¡Ama a las fechas por encima de todo, especialmente cuando estás desarrollando una aplicación!.

Durante años hemos tenido que pelearnos con las fechas. Ya sea trabajando con una base de datos o directamente desde el lenguaje de programación, tarde o temprano nos encontramos con el mismo problema: los formatos de fecha no siempre son los que queremos mostrar al usuario.

Y claro, no es lo mismo que nuestro cliente vea:

20th April 2018

que algo bastante más natural para nosotros:

20 de abril de 2018

Muchos CMS como WordPress nos facilitan enormemente esta tarea. Pero siempre puede aparecer un proyecto en el que tengamos que desarrollar nuestra propia aplicación sin utilizar ningún CMS.

Y aquí es donde tenemos que empezar a trabajar directamente con PHP.


El problema con las fechas en PHP

PHP dispone de muchas herramientas para trabajar con fechas, pero hay que distinguir entre generar una fecha, formatearla y traducir sus nombres al español.

Por ejemplo:

<?php

$fecha = new DateTime();

echo $fecha->format('d/m/Y');

Esto podría devolver:

20/08/2026

Perfecto.

Pero si queremos algo más descriptivo:

20 de agosto de 2026

necesitamos hacer algo más.


La solución moderna: IntlDateFormatter

En PHP moderno, una de las opciones más adecuadas para mostrar fechas localizadas es utilizar la extensión Intl, basada en ICU.

Esto nos permite indicar directamente que queremos trabajar con el idioma español.

Por ejemplo:

<?php

$fecha = new DateTime();

$formateador = new IntlDateFormatter(
    'es_ES',
    IntlDateFormatter::LONG,
    IntlDateFormatter::NONE
);

echo $formateador->format($fecha);

El resultado será similar a:

20 de agosto de 2026

Mucho más sencillo y, sobre todo, más apropiado para aplicaciones actuales.


Mostrar una fecha con el formato que nosotros queramos

También podemos utilizar IntlDateFormatter con un patrón personalizado.

Por ejemplo:

<?php

$fecha = new DateTime();

$formateador = new IntlDateFormatter(
    'es_ES',
    IntlDateFormatter::NONE,
    IntlDateFormatter::NONE,
    'Europe/Madrid',
    IntlDateFormatter::GREGORIAN,
    "d 'de' MMMM 'de' yyyy"
);

echo $formateador->format($fecha);

Obtendremos:

20 de agosto de 2026

Podemos modificar el patrón para adaptarlo a las necesidades de nuestro proyecto.


¿Y si tenemos una fecha procedente de MySQL?

Esta situación es probablemente mucho más habitual en una aplicación real.

Imaginemos que nuestra base de datos almacena una fecha de esta manera:

2026-08-20 14:35:00

Podemos convertirla en un objeto DateTime y posteriormente utilizar nuestro formateador:

<?php

$fecha = new DateTime('2026-08-20 14:35:00');

$formateador = new IntlDateFormatter(
    'es_ES',
    IntlDateFormatter::NONE,
    IntlDateFormatter::NONE,
    'Europe/Madrid',
    IntlDateFormatter::GREGORIAN,
    "d 'de' MMMM 'de' yyyy"
);

echo $formateador->format($fecha);

Resultado:

20 de agosto de 2026

Y ya tenemos nuestra fecha almacenada en formato SQL convertida en una fecha legible para el usuario.


Mostrar también la hora

Si además queremos mostrar la hora, podemos utilizar un patrón diferente:

<?php

$fecha = new DateTime('2026-08-20 14:35:00');

$formateador = new IntlDateFormatter(
    'es_ES',
    IntlDateFormatter::LONG,
    IntlDateFormatter::SHORT,
    'Europe/Madrid'
);

echo $formateador->format($fecha);

El resultado será similar a:

20 de agosto de 2026, 14:35

De esta manera podemos localizar tanto la fecha como la hora.


¿Qué pasa con strftime()?

Aquí tenemos una diferencia importante respecto al artículo original.

Durante muchos años era habitual encontrar ejemplos como este:

<?php

setlocale(LC_TIME, 'es_ES.UTF-8');

echo strftime('%d de %B de %Y');

El problema es que strftime() fue declarado obsoleto en PHP 8.1 y no deberíamos utilizarlo en código nuevo.

Por tanto, aunque encontremos este método en multitud de tutoriales antiguos, actualmente es preferible utilizar IntlDateFormatter cuando necesitamos localización de fechas.

Importante si estás actualizando código antiguo

Si encuentras un proyecto antiguo que utiliza strftime(), no significa necesariamente que vaya a dejar de funcionar inmediatamente, pero conviene migrarlo si estás actualizando el proyecto a versiones modernas de PHP.


El problema de setlocale()

Otro detalle que suele provocar dolores de cabeza es setlocale().

En el código antiguo era habitual encontrarnos con:

setlocale(LC_TIME, 'es_ES.UTF-8');

o, en Windows:

setlocale(LC_TIME, 'spanish');

Esto dependía del sistema operativo y, además, de que el locale correspondiente estuviera instalado y disponible.

Por eso un código que funcionaba perfectamente en nuestro servidor Linux podía comportarse de manera diferente cuando lo ejecutábamos en Windows o en otro entorno.

Con IntlDateFormatter podemos especificar directamente:

'es_ES'

sin tener que depender de que el sistema tenga configurado exactamente el mismo locale.


Comprobar si tenemos instalada la extensión Intl

Para utilizar IntlDateFormatter, nuestra instalación de PHP necesita disponer de la extensión Intl.

Podemos comprobarlo rápidamente:

<?php

var_dump(class_exists('IntlDateFormatter'));

Si obtenemos:

bool(true)

la clase está disponible.

También podemos comprobar desde la consola:

php -m | grep intl

En Windows podemos utilizar:

php -m | findstr intl

Si no aparece, tendremos que habilitar o instalar la extensión intl dependiendo de nuestro entorno.


Un ejemplo completo

Vamos a juntar todo en un pequeño ejemplo que podríamos utilizar directamente en una aplicación:

<?php

date_default_timezone_set('Europe/Madrid');

$fecha = new DateTime('2026-08-20 14:35:00');

$formateador = new IntlDateFormatter(
    'es_ES',
    IntlDateFormatter::NONE,
    IntlDateFormatter::NONE,
    'Europe/Madrid',
    IntlDateFormatter::GREGORIAN,
    "d 'de' MMMM 'de' yyyy"
);

echo 'Hoy es: ' . $formateador->format($fecha);

Resultado:

Hoy es: 20 de agosto de 2026

Una alternativa sencilla: traducir el mes manualmente

Si estamos realizando algo extremadamente sencillo y no queremos utilizar Intl, también podemos formatear la fecha con DateTime y traducir los nombres de los meses nosotros mismos.

Por ejemplo:

<?php

$meses = [
    1 => 'enero',
    2 => 'febrero',
    3 => 'marzo',
    4 => 'abril',
    5 => 'mayo',
    6 => 'junio',
    7 => 'julio',
    8 => 'agosto',
    9 => 'septiembre',
    10 => 'octubre',
    11 => 'noviembre',
    12 => 'diciembre'
];

$fecha = new DateTime();

echo $fecha->format('d') . ' de '
    . $meses[(int) $fecha->format('n')]
    . ' de '
    . $fecha->format('Y');

Esto produciría algo como:

20 de agosto de 2026

Es una solución perfectamente válida para casos sencillos, aunque para una aplicación que necesite trabajar con diferentes idiomas, formatos y localizaciones, Intl será una opción mucho más completa.


¿Y si necesitamos varios idiomas?

Aquí es donde IntlDateFormatter empieza a demostrar todo su potencial.

Podemos cambiar simplemente el locale:

$formateador = new IntlDateFormatter(
    'es_ES',
    IntlDateFormatter::LONG,
    IntlDateFormatter::NONE
);

Español:

'es_ES'

Inglés:

'en_US'

Francés:

'fr_FR'

Alemán:

'de_DE'

De esta manera podemos adaptar nuestra aplicación al idioma seleccionado por el usuario sin tener que crear manualmente todos los nombres de los meses y días.


¿Qué solución deberíamos utilizar hoy?

Si estamos trabajando con un proyecto antiguo y nos encontramos con:

setlocale(LC_TIME, ...);
strftime(...);

conviene saber que estamos ante una solución de otra época.

Para código nuevo en PHP moderno, una opción recomendable es:

DateTime
+
IntlDateFormatter

De esta forma separamos claramente dos responsabilidades:

  • DateTime: trabajar con la fecha y la hora.
  • IntlDateFormatter: presentar esa fecha según el idioma y la localización deseada.

Conclusión

Mostrar fechas en español desde PHP no tiene por qué convertirse en una pelea constante con los formatos, los locales y los sistemas operativos.

En código antiguo podemos encontrarnos con setlocale() y strftime(), pero para proyectos modernos es preferible utilizar las herramientas de internacionalización proporcionadas por PHP mediante la extensión Intl.

Con unas pocas líneas podemos transformar:

2026-08-20 14:35:00

en algo mucho más agradable para nuestro usuario:

20 de agosto de 2026, 14:35

Y si mañana nuestro cliente nos dice que quiere la aplicación en inglés, francés o alemán, tampoco tendremos que empezar a traducir los meses a mano.

Porque una cosa es programar una aplicación y otra muy distinta es obligar al usuario a leer:

20th August 2026

cuando podemos darle algo mucho más nuestro:

20 de agosto de 2026. 😉

Visitas: 1696

Website |  + posts

Automation & Data Specialist | Web Development | Data Processing & Integration

Deja un comentario