Как я могу легко конвертировать даты из UTC через PHP? - PullRequest
8 голосов
/ 05 июня 2009

Я храню даты в базе данных MySQL в полях datetime в UTC. Я использую PHP, и я вызвал date_timezone_set ('UTC'), чтобы все вызовы date () (без метки времени) возвращали дату в UTC.

У меня тогда есть, чтобы данный веб-сайт мог выбрать свой часовой пояс. Теперь я хочу, чтобы даты отображались в часовом поясе сайта. Итак, если у меня дата хранится как «2009-04-01 15:36:13», она должна отображаться для пользователя в часовом поясе PDT (-7 часов) как «2009-04-01 08:36:13» .

Какой самый простой (наименьший код) метод для этого через PHP? Пока все, о чем я думал, это

date('Y-m-d H:i:s', strtotime($Site->getUTCOffset() . ' hours', strtotime(date($utcDate))));

Есть ли более короткий путь?

Ответы [ 8 ]

18 голосов
/ 05 июня 2009

Почему бы не использовать встроенную функцию DateTime / TimeZone ?

<?php

$mysqlDate = '2009-04-01 15:36:13';

$dateTime = new DateTime ($mysqlDate);
$dateTime->setTimezone(new DateTimeZone('America/Los_Angeles'));

?>

DateTime Класс: http://us3.php.net/manual/en/class.datetime.php Класс DateTimeZone: http://us3.php.net/manual/en/class.datetimezone.php

Поддерживаемые PHP часовые пояса: http://php.net/manual/en/timezones.php

8 голосов
/ 19 апреля 2011

То, что вы делаете, является правильным способом ведения дел. Я бы порекомендовал придерживаться работы только в формате UTC и просто конвертировать в последнюю минуту для отображения.

Вот быстрая функция, которую я собрал для преобразования часового пояса с использованием класса DateTime, который поставляется с PHP. Это немного больше кода, чем у вас, но я думаю, что это проще и лучший способ структурировать вещи ...

function convert_time_zone($date_time, $from_tz, $to_tz)
    {
    $time_object = new DateTime($date_time, new DateTimeZone($from_tz));
    $time_object->setTimezone(new DateTimeZone($to_tz));
    return $time_object->format('Y-m-d H:i:s');
    }

http://richardwillia.ms/blog/2011/04/time-zone-conversion-using-datetime-class/

Надеюсь, это поможет.

7 голосов
/ 08 июня 2009

Вот что мы сделали с нашими серверами. Мы устанавливаем все, чтобы использовать UTC, и мы отображаем в часовом поясе пользователя, конвертируя из UTC на лету. Код внизу этого поста - пример того, как заставить это работать; вы должны подтвердить, что он работает во всех случаях с вашей настройкой (т. е. переход на летнее время и т. д.).

Настройка CentOS

  1. Редактировать /etc/sysconfig/clock и установить ZONE на UTC
  2. ln -sf /usr/share/zoneinfo/UTC /etc/localtime

Настройка MySQL

  1. Импорт часовых поясов в MySQL, если необходимо:

    mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql

  2. Отредактируйте my.cnf и добавьте следующее в раздел [mysqld]:

    default-time-zone = 'UTC'

PHP-код

<?php
/*
Example usage:
  $unixtime = TimeUtil::dateTimeToTimestamp('2009-04-01 15:36:13');
  echo TimeUtil::UTCToPST("M d, Y - H:i:s", $unixtime);
*/

// You should move this to your regular init method
date_default_timezone_set('UTC'); // make this match the server timezone

class TimeUtil {
    public static function timestampToDateTime($timestamp) {
        return gmdate('Y-m-d H:i:s', $timestamp);
    }

    public static function dateTimeToTimestamp($dateTime) {
        // dateTimeToTimestamp expects MySQL format
        // If it gets a fully numeric value, we'll assume it's a timestamp
        // You can comment out this if block if you don't want this behavior
        if(is_numeric($dateTime)) {
            // You should probably log an error here
            return $dateTime;
        }
        $date = new DateTime($dateTime); 
        $ret = $date->format('U');
        return ($ret < 0 ? 0 : $ret);
    }

    public static function UTCToPST($format, $time) {
        $dst = intval(date("I", $time));
        $tzOffset = intval(date('Z', time()));
        return date($format, $time + $tzOffset - 28800 + $dst * 3600);
    }

}
1 голос
/ 18 января 2012
<?php

  function getNoteDateTimeZone($date = null, $from_dtz = 'US/Central', $to_dtz = null) {
        //$from_zt = 'US/Central'; // Time Zone = -06:00
        if (is_null($date) == FALSE && is_null($from_dtz) == FALSE && is_null($to_dtz) == FALSE) {
            // set TimeZone from
            $time_object = new DateTime($date, new DateTimeZone($from_dtz));
            $time_now_object = new DateTime("now", new DateTimeZone($from_dtz));
            // Change TimeZone
            $time_object->setTimezone(new DateTimeZone(trim($to_dtz)));
            $time_now_object->setTimezone(new DateTimeZone(trim($to_dtz)));
            // Is day = day in $time_now_object, $time_object..?
            if ($time_now_object->format('d') == $time_object->format('d')) {
                return $time_object->format('H:i:s');
            } else {
                return $time_object->format('Y-m-d H:i:s');
            }
        } else {
            return '';
        }
    }
?>

Использовать образец:

<?php 
 $date = '2008-06-02 20:32:46';
 $dtz = 'America/Argentina/Buenos_Aires';
 echo getNoteDateTimeZone($date, 'US/Central', $dtz); // Out = 2008-06-02 23:32:46
?>
1 голос
/ 08 июня 2009

Потратив много времени на решение этой проблемы, не пытайтесь самостоятельно осуществлять перевод часовых поясов. Это королевская PIA, сопряженная с трудностями, и очень трудно понять ее на международном уровне.

Тем не менее, лучший вариант - преобразовать ваши datetime s в MySQL в timestamp s и просто использовать базу данных для преобразования времени:

 mysql> set time_zone='America/New_York';

отметка времени с в MySQL меньше и поддерживают перевод часовых поясов. datetime нет.

Перед тем, как отобразить информацию о сайте на странице, просто вызовите указанную выше команду, и она будет отображаться правильно, без каких-либо изменений кода PHP.

Предостережения:

  1. Если вы используете NOW () или любые другие функции местного времени, вам следует обновить их до UTC_TIMESTAMP ()
  2. отметка времени s содержит интересные обновления и вставляет свойства, которые вы можете отключить.

Для отключения отметка времени свойства:

ALTER TABLE mytable CHANGE COLUMN Created Created timestamp NULL DEFAULT 0;

DEFAULT 0 отключает обновление столбца при обновлении других столбцов.

0 голосов
/ 03 марта 2016

Преобразование часового пояса пользователя в часовой пояс сервера и наоборот с помощью одной функции:

function convertTimeZone($date, $convertTo = 'userTimeZone', $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC', $format = 'n/j/Y g:i A')
{
    if($convertTo == 'userTimeZone'){
       $dateTime = new DateTime ($date, new DateTimeZone($serverTimeZone));
       $dateTime->setTimezone(new DateTimeZone($userTimeZone));
       return $dateTime->format($format);   
    } else if($convertTo == 'serverTimeZone'){
       $dateTime = new DateTime ($date, new DateTimeZone($userTimeZone));
       $dateTime->setTimezone(new DateTimeZone($serverTimeZone));
       return $dateTime->format($format);   
    }
}

echo convertTimeZone(date('Ydm h:i:s'),'serverTimeZone');
0 голосов
/ 30 января 2014

Это сработало для меня, и это довольно чисто

function convert_to_user_date($date, $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC', $format = 'n/j/Y g:i A')
{
    $dateTime = new DateTime ($date, new DateTimeZone($serverTimeZone));
    $dateTime->setTimezone(new DateTimeZone($userTimeZone));
    return $dateTime->format($format);
}

function convert_to_server_date($date, $userTimeZone = 'America/Los_Angeles', $serverTimeZone = 'UTC', $format = 'n/j/Y g:i A')
{
    $dateTime = new DateTime ($date, new DateTimeZone($userTimeZone));
    $dateTime->setTimezone(new DateTimeZone($serverTimeZone));
    return $dateTime->format($format);
}
0 голосов
/ 07 ноября 2009
ADDTIME($utcDate,$Site->getUTCOffset())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...