2010-09-23 4 views
5

J'ai une application cakePHP qui tire des données à partir de deux bases de données différentes, qui stockent des dates et des heures dans leurs données à partir de fuseaux horaires différents. Le fuseau horaire d'une base de données est Europe/Berlin et celui de l'autre est Australia/Sydney. Pour compliquer les choses, l'application est hébergée sur un serveur aux États-Unis et les heures doivent être présentées à l'utilisateur final dans son fuseau horaire local.convertir des dates entre les fuseaux horaires dans AppModel-> afterFind (cakePHP)

Il est assez facile de dire à quelle base de données j'ai accès, et donc j'ai défini le fuseau horaire approprié (en utilisant date_default_timezone_set()) dans mon beforeFind afin que la requête soit envoyée avec une date dans le fuseau horaire correct.

Mon problème est alors la conversion des dates dans le afterFind au fuseau horaire de l'utilisateur. Je passe ce fuseau horaire en tant que paramètre nommé, et pour y accéder dans le modèle, j'utilise Configure::write() et Configure.read(). Cela fonctionne bien.
Le problème est qu'il semble appliquer ma conversion timezone plusieurs fois. Par exemple, si j'interroge la base de données Australia/Sydney à partir de Australia/Perth, le délai devrait être de deux heures, mais six heures plus tard. J'ai essayé de faire écho aux temps de ma fonction avant et après les avoir convertis, et chaque conversion fonctionnait correctement, mais elle convertissait les temps plus d'une fois, et je n'arrive pas à comprendre pourquoi.

Les méthodes que je suis en train d'utiliser (dans mon AppModel) pour convertir d'un fuseau horaire à l'autre est la suivante:

function afterFind($results, $primary){ 
    // Only bother converting if the local timezone is set. 
    if(Configure::read('TIMEZONE')) 
     $this->replaceDateRecursive($results); 
    return $results; 
} 

function replaceDateRecursive(&$results){ 
    $local_timezone = Configure::read('TIMEZONE'); 

    foreach($results as $key => &$value){ 
     if(is_array($value)){ 
      $this->replaceDateRecursive($value); 
     } 
     else if(strtotime($value) !== false){ 
      $from_timezone = 'Europe/Berlin'; 
      if(/* using the Australia/Sydney database */) 
       $from_timezone = 'Australia/Sydney'; 
      $value = $this->convertDate($value, $from_timezone, $local_timezone, 'Y-m-d H:i:s'); 
     } 
    } 
} 

function convertDate($value, $from_timezone, $to_timezone, $format = 'Y-m-d H:i:s'){ 
    date_default_timezone_set($from_timezone); 
    $value = date('Y-m-d H:i:s e', strtotime($value)); 
    date_default_timezone_set($to_timezone); 
    $value = date($format, strtotime($value)); 

    return $value;      
} 

Cela veut-il que quelqu'un a des idées pour expliquer pourquoi la conversion se produit plusieurs fois? Ou est-ce que quelqu'un a une meilleure méthode pour convertir les dates? Je fais évidemment quelque chose de mal, je suis juste coincé sur ce que c'est.

+0

Merci pour ce code, j'ai fini par faire quelque chose de vraiment similaire. –

Répondre

2

J'ai élaboré une solution. Je n'ai pas vraiment compris ce que le paramètre $primary dans le afterFind était pour jusqu'à maintenant. Donc, pour fixer mon code ci-dessus, tout ce que je dois faire est de changer le if dans le afterFind aux personnes suivantes:

function afterFind($results, $primary){ 
    // Only bother converting if these are the primary results and the local timezone is set. 
    if($primary && Configure::read('TIMEZONE')) 
     $this->replaceDateRecursive($results); 
    return $results; 
} 

Comme une note de côté, je ne suis plus en utilisant la fonction date_default_timezone_set() pour effectuer la conversion de fuseau horaire, soit . Ma fonction convertDate a changé comme suit:

function convertDate($value, $from_timezone, $to_timezone, $format = 'Y-m-d H:i:s'){ 
    $dateTime = new DateTime($value, new DateTimeZone($from_timezone)); 
    $dateTime->setTimezone(new DateTimeZone($to_timezone)); 
    $value = $dateTime->format($format); 

    return $value;      
} 
Questions connexes