Cómo localizar fechas y horas en PHP

Localización en PHP

En un proyecto PHP en el que estoy participando tenemos problemas para mostrar las fechas en el idioma que queremos, en este caso en español. En esta entrada te explico cómo localizar fechas y horas en PHP.

setlocale

PHP dispone de la función setlocale, que te permite establecer la información del localismo. Puedes localizar varios elementos, como puedes comprobar en la documentación de referencia de setlocale, pero para fechas y horas es suficiente usar el parámetro «LC_TIME».

Por lo tanto, tendrás que usar la función:

setlocale(LC_TIME, 'es_ES');

donde:

Para comprobar si esto funciona uso la función strftime(), que formatea una fecha/hora local según una configuración local. El parámetro «%B» devuelve el nombre completo del mes:

<?php
setlocale(LC_TIME, 'es_ES');
echo strftime('%B') . PHP_EOL;

Si lo ejecuto:

$ php test.php
August

El resultado está en inglés. ¿Por qué sucede esto?

Antes de nada, compruebo qué equipo estoy usando. Las pruebas las estoy ejecutando en un equipo con Ubuntu 20.04 LTS y PHP 7.4.

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04 LTS
Release:        20.04
Codename:       focal

$ php -v
PHP 7.4.7 (cli) (built: Jun 12 2020 07:44:38) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.7, Copyright (c), by Zend Technologies

El problema está en que la máquina no tiene instalada la localización de español de España.

Para comprobar las localizaciones disponibles hay que ejecutar:

$ locale -a
C
C.UTF-8
en_AG
en_AG.utf8
en_AU.utf8
en_BW.utf8
en_CA.utf8
en_DK.utf8
en_GB.utf8
en_HK.utf8
en_IE.utf8
en_IL
en_IL.utf8
en_IN
en_IN.utf8
en_NG
en_NG.utf8
en_NZ.utf8
en_PH.utf8
en_SG.utf8
en_US.utf8
en_ZA.utf8
en_ZM
en_ZM.utf8
en_ZW.utf8
POSIX

Puedes comprobar si entre los locales soportados por el sistema se encuentran los de español ejecutando:

$ more /usr/share/i18n/SUPPORTED | grep es_ES
es_ES.UTF-8 UTF-8
es_ES ISO-8859-1
es_ES@euro ISO-8859-15

Para generar los ficheros de localización desde las plantillas hay que ejecutar:

$ sudo locale-gen es_ES.UTF-8 es_ES es_ES@euro
Generating locales (this might take a while)...
  es_ES.ISO-8859-15@euro... done
  es_ES.ISO-8859-1... done
  es_ES.UTF-8... done
Generation complete.

Ahora ya aparece instalado el locale de español:

$ locale -a | grep es_ES
es_ES
es_ES@euro
es_ES.iso88591
es_ES.iso885915@euro
es_ES.utf8

Si ejecutas el código anterior, puedes ver que ahora la información se muestra en español:

$ php test.php
agosto

Ten en cuenta que la función date() no permite la localización. La propia documentación de PHP indica que:

Para formatear fechas en otros lenguajes debería usar las funciones setlocale() y strftime() en vez de date().

Si ejecutas este código:

<?php
setlocale(LC_TIME, 'es_ES');
echo date('F') . PHP_EOL;

El resultado está en inglés:

$ php test.php
August

Lo mismo ocurre con DateTime():

<?php
setlocale(LC_TIME, 'es_ES');
$date = new DateTime();
echo $date->format('F') . PHP_EOL;

Cuyo resultado es:

$ php test.php
August

Lo que puedes hacer es pasarle el timestamp del objeto a la función strftime:

<?php
setlocale(LC_TIME, 'es_ES');
$date = new DateTime('2020-08-02T15:03:01.012345Z', new DateTimeZone('Europe/Madrid'));
echo strftime("%B", $date->getTimestamp()) . PHP_EOL;

Ahora la salida sí que es correcta

$ php test.php
agosto

Puedes encontrar más información sobre cómo localizar fechas y horas en PHP en este enlace.

1 comment

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.