php преобразовать дату и время в UTC

90

Мне нужен простой способ конвертировать метку даты и времени в UTC (из любого часового пояса, в котором находится сервер) НАДЕЖНО без использования каких-либо библиотек.

Джереми
источник

Ответы:

30

Попробуйте getTimezone и setTimezone , см. Пример

(Но здесь используется класс)

ОБНОВИТЬ:

Без каких-либо классов вы можете попробовать что-то вроде этого:

$the_date = strtotime("2010-01-19 00:00:00");
echo(date_default_timezone_get() . "<br />");
echo(date("Y-d-mTG:i:sz",$the_date) . "<br />");
echo(date_default_timezone_set("UTC") . "<br />");
echo(date("Y-d-mTG:i:sz", $the_date) . "<br />");

ПРИМЕЧАНИЕ. Возможно, вам также потребуется установить часовой пояс обратно на исходный.

Фил Паффорд
источник
56
Вы должны просто использовать gmdateвместо изменения часового пояса по умолчанию на UTC. Потому что gmdateавтоматически использует UTC.
poke
30
-1, потому что вы не хотите менять для этого глобальный часовой пояс по умолчанию. Он просто просит о непредвиденных побочных эффектах.
Уорд Беккер,
@Phill Что здесь "sz"?
Шахид Карими
2
Я думаю, это должно быть «Ym-dTG ...» вместо «Yd-mTG ...»
Alex Angelico
Это не работает для меня в проекте laravel. Его возвращение в тот же день
Дхармендер Тули
109

Используйте strtotime, чтобы сгенерировать метку времени из заданной строки (интерпретируемой как местное время), и используйте gmdate, чтобы получить ее как дату в формате UTC назад.

пример

По запросу, вот простой пример:

echo gmdate('d.m.Y H:i', strtotime('2012-06-28 23:55'));
тыкать
источник
2
@cherouvim Не думаю, что это необходимо, но все равно добавил… Надеюсь, это поможет.
poke
5
gmdate () - одна из тех функций PHP, на которые я хотел бы наткнуться давным-давно. nl2br, кто-нибудь?
Чарли Шлиссер
1
GMT и UTC не всегда одинаковы.
Джей Шет
@JaySheth Фактически, UTC и GMT являются синонимами.
тыкает
1
@poke GMT учитывает переход на летнее время, UTC - нет, и поэтому он используется, поэтому вам не нужно учитывать что-либо еще
Necro
72

Использование DateTime:

$given = new DateTime("2014-12-12 14:18:00");
echo $given->format("Y-m-d H:i:s e") . "\n"; // 2014-12-12 14:18:00 Asia/Bangkok

$given->setTimezone(new DateTimeZone("UTC"));
echo $given->format("Y-m-d H:i:s e") . "\n"; // 2014-12-12 07:18:00 UTC
Joerx
источник
В вопросе говорится, что нужно преобразовать метку времени в метку времени, а DateTime не принимает метку времени в качестве входных данных. Вам нужно будет каким-то образом преобразовать его в строку, а затем преобразовать обратно.
felwithe
14

Если у вас есть дата в этом формате ГГГГ-ММ-ЧЧ дд: мм: сс, вы можете обмануть php, добавив UTC в конце вашей «строки даты и времени» и используя strtotime для его преобразования.

date_default_timezone_set('Europe/Stockholm');
print date('Y-m-d H:i:s',strtotime("2009-01-01 12:00"." UTC"))."\n";
print date('Y-m-d H:i:s',strtotime("2009-06-01 12:00"." UTC"))."\n";

Это напечатает это:

2009-01-01 13:00:00
2009-06-01 14:00:00

И, как видите, он также решает проблему перехода на летнее время.

Немного странный способ решить .... :)

Йохан
источник
Я действительно не понимаю, почему OP не выбрал ваше предложение:D
php_nub_qq
@php_nub_qq, вероятно, потому, что он работает, изменяя часовой пояс для всего скрипта, что может быть нежелательным и может иметь непредвиденные последствия.
felwithe
@felwithe Не было бы, если бы вы пропустили первую строку, которая предназначена только для демонстрации
php_nub_qq
11

Преобразование строки местного часового пояса в строку UTC.
например, часовой пояс Новой Зеландии

$datetime = "2016-02-01 00:00:01";
$given = new DateTime($datetime, new DateTimeZone("Pacific/Auckland"));
$given->setTimezone(new DateTimeZone("UTC"));
$output = $given->format("Y-m-d H:i:s"); 
echo ($output);
  • NZDT: UTC + 13: 00,
    если $ datetime = "2016-02-01 00:00:01", $ output = "2016-01-31 11:00:01";
    если $ datetime = "2016-02-29 23:59:59", $ output = "2016-02-29 10:59:59";
  • NZST: UTC + 12: 00,
    если $ datetime = "2016-05-01 00:00:01", $ output = "2016-04-30 12:00:01";
    если $ datetime = "2016-05-31 23:59:59", $ output = "2016-05-31 11:59:59";

https://en.wikipedia.org/wiki/Time_in_New_Zealand

Франк Хоу
источник
6

Если вы не против использовать класс PHP DateTime , который доступен с PHP 5.2.0, то есть несколько сценариев, которые могут соответствовать вашей ситуации:

  1. Если у вас есть $givenDtобъект DateTime, который вы хотите преобразовать в UTC, он преобразует его в UTC:

    $givenDt->setTimezone(new DateTimeZone('UTC'));
    
  2. Если вам понадобится оригинал $givenDtпозже, вы также можете захотеть клонировать данный объект DateTime перед преобразованием клонированного объекта:

    $utcDt = clone $givenDt;
    $utcDt->setTimezone(new DateTimeZone('UTC'));
    
  3. Если у вас есть только строка datetime, например $givenStr = '2018-12-17 10:47:12', тогда вы сначала создаете объект datetime, а затем конвертируете его. Обратите внимание, это предполагает, что это $givenStrнаходится в настроенном часовом поясе PHP.

    $utcDt = (new DateTime($givenStr))->setTimezone(new DateTimeZone('UTC'));
    
  4. Если указанная строка datetime находится в каком-либо часовом поясе, отличном от часового пояса в вашей конфигурации PHP, создайте объект datetime, указав правильный часовой пояс (см. Список часовых поясов, поддерживаемых PHP ). В этом примере мы предполагаем местный часовой пояс в Амстердаме:

    $givenDt = new DateTime($givenStr, new DateTimeZone('Europe/Amsterdam'));
    $givenDt->setTimezone(new DateTimeZone('UTC'));
    
Копролал
источник
4

Поскольку strtotime требует определенного формата ввода, можно использовать DateTime :: createFromFormat ( требуется php 5.3+ )

// set timezone to user timezone
date_default_timezone_set($str_user_timezone);

// create date object using any given format
$date = DateTime::createFromFormat($str_user_dateformat, $str_user_datetime);

// convert given datetime to safe format for strtotime
$str_user_datetime = $date->format('Y-m-d H:i:s');

// convert to UTC
$str_UTC_datetime = gmdate($str_server_dateformat, strtotime($str_user_datetime));

// return timezone to server default
date_default_timezone_set($str_server_timezone);
Христос Понтикис
источник
4

Иногда я использую этот метод:

// It is not importnat what timezone your system is set to.
// Get the UTC offset in seconds:
$offset = date("Z");

// Then subtract if from your original timestamp:
$utc_time = date("Y-m-d H:i:s", strtotime($original_time." -".$offset." Seconds"));

Работает все MOST времени.

аорчик
источник
3
Тут две проблемы. Во-первых, вы не должны вычитать, вы должны добавить смещение. Во-вторых, это не работает, если местный часовой пояс в настоящее время находится на летнем времени, а желаемая дата не на летнем времени. Смещение будет отключено на час. Или наоборот. Так что да, это работает В большинстве случаев, но не всегда.
ajon
1

С PHP 5 или выше вы можете использовать функцию datetime :: format (см. Документацию http://us.php.net/manual/en/datetime.format.php )

 echo strftime( '%e %B %Y' , 
    date_create_from_format('Y-d-m G:i:s', '2012-04-05 11:55:21')->format('U')
    );  // 4 May 2012
MUY Бельгия
источник
0

пытаться

эхо-дата ('F d Y', strtotime ('2010-01-19 00:00:00'));

выведет:

19 января 2010 г.

вы должны изменить формат времени, чтобы увидеть другой вывод

StevieJ
источник
0

Функция нормализации общего назначения для форматирования любой временной метки из любого часового пояса в другой. Очень полезно для хранения отметок времени пользователей из разных часовых поясов в реляционной базе данных. Для сравнения баз данных сохраните метку времени как UTC и используйте сgmdate('Y-m-d H:i:s')

/**
 * Convert Datetime from any given olsonzone to other.
 * @return datetime in user specified format
 */

function datetimeconv($datetime, $from, $to)
{
    try {
        if ($from['localeFormat'] != 'Y-m-d H:i:s') {
            $datetime = DateTime::createFromFormat($from['localeFormat'], $datetime)->format('Y-m-d H:i:s');
        }
        $datetime = new DateTime($datetime, new DateTimeZone($from['olsonZone']));
        $datetime->setTimeZone(new DateTimeZone($to['olsonZone']));
        return $datetime->format($to['localeFormat']);
    } catch (\Exception $e) {
        return null;
    }
}

Применение:

$from = ['localeFormat' => "d/m/Y H:i A", 'olsonZone' => 'Asia/Calcutta'];

$to = ['localeFormat' => "Y-m-d H:i:s", 'olsonZone' => 'UTC'];

datetimeconv("14/05/1986 10:45 PM", $from, $to); // returns "1986-05-14 17:15:00"
Сандип
источник
0

в качестве альтернативы вы можете попробовать это:

<?php echo (new DateTime("now", new DateTimeZone('Asia/Singapore')))->format("Y-m-d H:i:s e"); ?>

это выведет:

2017-10-25 17:13:20 Азия / Сингапур

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

удалите букву "e", если вы не хотите показывать свой регион / страну.

Брюс Тонг
источник
0

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

  1. Javascript (на стороне клиента):

    var dateVar = new Date();
    var offset = dateVar.getTimezoneOffset();
    //getTimezoneOffset - returns the timezone difference between UTC and Local Time
    document.cookie = "offset="+offset;
    
  2. Php (на стороне сервера):

    public function convert_utc_time($date)
    {
        $time_difference = isset($_COOKIE['offset'])?$_COOKIE['offset']:'';
        if($time_difference != ''){
            $time = strtotime($date);
            $time = $time + ($time_difference*60); //minutes * 60 seconds
            $date = date("Y-m-d H:i:s", $time);
        } //on failure of js, default timezone is set as UTC below
        return $date;
    }
    ..
    ..
    //in my function
    $timezone = 'UTC';
    $date = $this->convert_utc_time($post_date); //$post_date('Y-m-d H:i:s')
    echo strtotime($date. ' '. $timezone)
    
Прадип Кумар Прабахаран
источник
-1

Как улучшение ответа Филла Паффорда (я не понял его «Yd-mTG: i: sz», и он предложил вернуть часовой пояс). Итак, я предлагаю это (я усложнил, изменив формат HMTL на простой / текстовый ...):

<?php
header('content-type: text/plain;');
$my_timestamp = strtotime("2010-01-19 00:00:00");

// stores timezone
$my_timezone = date_default_timezone_get();
echo date(DATE_ATOM, $my_timestamp)."\t ($my_timezone date)\n";

// changes timezone
date_default_timezone_set("UTC");
echo date("Y-m-d\TH:i:s\Z", $my_timestamp)."\t\t (ISO8601 UTC date)\n";
echo date("Y-m-d H:i:s", $my_timestamp)."\t\t (your UTC date)\n";

// reverts change
date_default_timezone_set($my_timezone);
echo date(DATE_ATOM, $my_timestamp)."\t ($my_timezone date is back)\n"; 
?>
7Тонин
источник
2
Вы должны отредактировать свой ответ, чтобы объяснить, как это улучшает ответ Фила. Что вы изменили в коде и почему он стал лучше?
Коди Грей
Изменение часового пояса PHP по умолчанию для преобразования двух временных меток - это действенный прием, но не изящное решение.
Копролал