Converting dates between time zones in AppModel-> afterFind (cakePHP)

I have a cakePHP application that retrieves data from two different databases that store dates and times in their data from different time zones. One database time zone Europe/Berlinand another - Australia/Sydney. To complicate the situation, the application is hosted on a server in the United States, and the time should be presented to the end user in the local time zone.

It’s easy enough to specify which database I should access, and so I set the appropriate time zone (using date_default_timezone_set()) in mine beforeFindso that the request is sent with the date in the correct time zone.

My problem is converting dates to afterFinduser timezone. I pass this time zone through a named parameter, and I use Configure::write()and to access it in the model Configure.read(). This works great.
The problem is that it seems to reapply my time zone. For example, if I request a database Australia/Sydneyfrom Australia/Perth, the time should be two hours behind, but it goes out in six hours. I tried to repeat the time from my function before and after their conversion, and each conversion worked correctly, but it converted times more than once, and I cannot understand why.

The methods I use (in mine AppModel) to convert from one time zone to another:

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;                    
}

- , ? - ? , , - , , .

+5
1

. , $primary afterFind. , , , , if afterFind :

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;
}

date_default_timezone_set() . convertDate :

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;                      
}
+2

All Articles