Преобразование часового пояса в php - PullRequest
49 голосов
/ 24 марта 2010

Может кто-нибудь предложить простой способ конвертировать дату и время в разные часовые пояса в php?

Ответы [ 8 ]

102 голосов
/ 24 марта 2010

Для этого вы можете использовать объект datetime или его псевдонимы функций:

Пример ( сокращено из PHP Manual )

date_default_timezone_set('Europe/London');

$datetime = new DateTime('2008-08-03 12:35:23');
echo $datetime->format('Y-m-d H:i:s') . "\n";
$la_time = new DateTimeZone('America/Los_Angeles');
$datetime->setTimezone($la_time);
echo $datetime->format('Y-m-d H:i:s');

Редактировать относительно комментариев

но я не могу использовать этот метод, потому что мне нужно показывать дату в разных часовых поясах при входе пользователя из разных мест

Это не проблема. Когда пользователь входит в систему, вы определяете его часовой пояс и устанавливаете его в свой объект DateTime, как показано на рисунке. Я использую подобный подход в одном из моих проектов, и он работает как шарм.

в базе данных мне нужно получить даты в любом часовом поясе, тогда только она может быть правильно обработана

Вы сохраняете время как метку времени или дату в одном часовом поясе. Когда вы запрашиваете поле DateTime, вы либо конвертируете время в объекте DateTime в этот часовой пояс, либо - если ваш БД его поддерживает - запрашиваете выбранный часовой пояс.

17 голосов
/ 23 октября 2013

Еще более простой метод выглядит так:

date_default_timezone_set('Europe/London'); // your user's timezone
$my_datetime='2013-10-23 15:47:10';
echo date('Y-m-d H:i:s',strtotime("$my_datetime UTC"));

Как описано в руководстве по PHP , strtotime () также принимает часовой пояс, вам просто нужно добавить его к вашей дате / времени.

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

11 голосов
/ 30 января 2014

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

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

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

//example usage
$serverDate = $userDate = '2014-09-04 22:37:22';
echo convert_to_user_date($serverDate);
echo convert_to_server_date($userDate);
7 голосов
/ 24 октября 2016

Ни один из этих ответов не сработал для меня (я пропустил попытку использования кода, который был слишком громоздким). Я также думаю, что странно менять часовой пояс по умолчанию только для одного преобразования.

Вот мое решение:

function changeTimeZone($dateString, $timeZoneSource = null, $timeZoneTarget = null)
{
  if (empty($timeZoneSource)) {
    $timeZoneSource = date_default_timezone_get();
  }
  if (empty($timeZoneTarget)) {
    $timeZoneTarget = date_default_timezone_get();
  }

  $dt = new DateTime($dateString, new DateTimeZone($timeZoneSource));
  $dt->setTimezone(new DateTimeZone($timeZoneTarget));

  return $dt->format("Y-m-d H:i:s");
}

Итак, чтобы преобразовать сервер в значение по умолчанию, вам нужно просто передать один часовой пояс:

changeTimeZone("2016-10-24 16:28", "Asia/Tokyo");

Чтобы преобразовать сервер по умолчанию для пользователя, вы должны оставить второй параметр пустым или пустым:

changeTimeZone("2016-10-24 16:28", "", "Asia/Tokyo");

А для переключения между часовыми поясами, не относящимися к значениям по умолчанию, вы должны указать 2 часовых пояса:

changeTimeZone("2016-10-24 16:28", "America/New_York", "Asia/Tokyo");
5 голосов
/ 04 июля 2014

DateTime :: setTimezone - date_timezone_set - устанавливает часовой пояс для объекта DateTime

Объектно-ориентированный стиль

<?php
$date = new DateTime('2000-01-01', new DateTimeZone('Pacific/Nauru'));
echo $date->format('Y-m-d H:i:sP') . "\n";

$date->setTimezone(new DateTimeZone('Pacific/Chatham'));
echo $date->format('Y-m-d H:i:sP') . "\n";
?>

Процедурный стиль

<?php
$date = date_create('2000-01-01', timezone_open('Pacific/Nauru'));
echo date_format($date, 'Y-m-d H:i:sP') . "\n";

date_timezone_set($date, timezone_open('Pacific/Chatham'));
echo date_format($date, 'Y-m-d H:i:sP') . "\n";
?>

Приведенные выше примеры выведут:

2000-01-01 00:00:00+12:00
2000-01-01 01:45:00+13:45
3 голосов
/ 26 июля 2016

UTC для местного:

<?php
$datetime = date("Y-m-d H:i:s");
$utc = new DateTime($datetime, new DateTimeZone('UTC'));
$utc->setTimezone(new DateTimeZone('America/Sao_Paulo'));
echo $utc->format('Y-m-d H:i:s');

?>
1 голос
/ 26 февраля 2016

// Преобразование даты из одной зоны в другую. / * $ Zone_from = 'Asia / Калькутта';

$zone_to='America/Phoenix';

date_default_timezone_set($zone_from);

$convert_date="2016-02-26 10:35:00";

echo $finalDate=zone_conversion_date($convert_date, $zone_from, $zone_to);

*/
function zone_conversion_date($time, $cur_zone, $req_zone)
{   
    date_default_timezone_set("GMT");
    $gmt = date("Y-m-d H:i:s");

    date_default_timezone_set($cur_zone);
    $local = date("Y-m-d H:i:s");

    date_default_timezone_set($req_zone);
    $required = date("Y-m-d H:i:s");

    /* return $required; */
    $diff1 = (strtotime($gmt) - strtotime($local));
    $diff2 = (strtotime($required) - strtotime($gmt));

    $date = new DateTime($time);
    $date->modify("+$diff1 seconds");
    $date->modify("+$diff2 seconds");

    return $timestamp = $date->format("Y-m-d H:i:s");
}
0 голосов
/ 12 октября 2015
<?php
$time='6:02';
$dt = new DateTime($time, new DateTimeZone('America/New_York'));
//echo $dt->format('Y-m-d H:i:s') . PHP_EOL;
$dt->setTimezone(new DateTimeZone('Asia/Kolkata'));
echo $dt->format('H:i') . PHP_EOL; 
?>
...