Tuesday 26 April 2011

Hora actual en cierto TimeZone con PHP5 usando date_create()

Tal vez te haya tocado pelearte con el tema de las zonas horarias... y sabrás que es un auténtico embrollo. Después de haber probado varios métodos, finalmente hallé para mis aplicaciones una manera bien sencilla, que aprovecho para compartir aquí.

El problema se trata de lo siguiente: necesito saber la hora actual en cierta zona horaria, teniendo en cuenta obviamente los cambios de hora para verano.

La solución:

1  <?php
2  
3       $timeZone 
"America/Hermosillo";
4       
$o_date date_create(nulltimezone_open($timeZone));
5       
$local_time date_format($o_date'd/m/Y H:i');
6            
7       echo 
"Time at ".$timeZone.": ".$local_time;
8            
9       
// will produce something like this
10       //
11       // Time at America/Hermosillo: 26/04/2011 13:32 
12  
13  
?>


Si en nuestro servidor poseemos una versión de PHP >= 5.3 podemos trabajar con una variante de lo anterior en la que usamos la función date_create_from_format() para crear el objeto de fecha $o_date a partir de cualquier fecha y hora en cualquier formato!!!

1  <?php
2  
3       $timeZone 
"America/Hermosillo";
4       
$o_date date_create_from_format('Y-m-d H:i','2011-04-26 00:00'timezone_open($timeZone));
5       
$local_time date_format($o_date'd/m/Y H:i');
6            
7       echo 
"Time at ".$timeZone.": ".$local_time;
8            
9       
// will produce something like this
10       //
11       // Time at America/Hermosillo: 25/04/2011 15:00 
12  
13  
?>


El inconveniente a día de hoy (Abril 2011) es que pocos servidores han actualizado aún a esa versión (el mío no, por ejemplo). En ese caso, este otro código que trabaja con objetos DateTime en lugar de con funciones, no es mucho más complicado pero nos aporta una nueva ventaja: podemos usar como "hora" a traducir cualquiera que esté en el formato Y-m-d H:i

1  <?php
2  
3       $timeZone 
'America/hermosillo';
4       
$dateTime = new DateTime('2011-04-26 00:00');
5       
$dateTime->setTimeZone(new DateTimeZone($timeZone));
6       
$local_time=$dateTime->format('d/m/Y H:i');
7  
8       echo 
"Time at ".$timeZone.": ".$local_time;
9  
10       
// will produce something like this
11       // (in a Server at 'Europe/Madrid')
12       //
13       // Time at America/Hermosillo: 25/04/2011 15:00
14        
15  
?> 


Es decir, resumiendo, el primer código que he presentado va excelente para calcular la hora en este momento en cualquier zona horaria del globo. Y el último código, nos es útil para calcular la hora en cualquier zona horaria a partir de cualquier otra fecha/hora de nuestro servidor ;)

Estoy seguro que a más de uno le ayudará esto. Aunque en realidad sé que la cosa aún puede complicarse más, y de hecho, si uno quiere que su aplicación web sea realmente "multi-horaria" (para el visitante, para la base de datos, etc...) la cosa puede ser un tanto surrealista. Una buena recomendación al respecto que leí hace unos meses es: guardar en tu base de datos fechas y horas en formato GMT, para a partir de ahí "traducirlo" al uso horario que necesites en cada momento, independientemente de que coloques tu aplicación en un servidor de una zona horaria u otra.

Suerte!
Salud!
SERGI

2 comments:

  1. gran post me sera de gran ayuda, muchas gracias por compartir

    ReplyDelete
  2. Gracias a ti Quim, por el feedback!

    Intento escribir un artículo cuando para resolver un problema concreto de programación he tenido que pasarme horas leyendo varias fuentes, probando varias cosas, descubriendo incompatibilidades con ciertas configuraciones/versiones de servidor/php, etc... si después de todo eso extraigo alguna conclusión interesante, entonces escribo un artículo para compartirlo.

    Un saludo!
    SERGI

    ReplyDelete