Как получить метку времени Unix в php на основе часового пояса - PullRequest
16 голосов
/ 29 декабря 2011

Сначала код

    echo time() . '<br/>';
echo date('Y-m-d H:i:s') . '<br/>';
date_default_timezone_set('America/New_York'); 

echo time() . '<br/>';
print_r($timezones[$timezone] . '<br/>');
echo date('Y-m-d H:i:s') . '<br/>';

В приведенном выше коде дата печатается в соответствии с часовым поясом, но метка времени unix остается неизменной даже после установки часового пояса по умолчанию

Как мы можем печатать метку времени unix в соответствии с часовым поясом

Ответы [ 5 ]

31 голосов
/ 29 декабря 2011

Ответ, предоставленный Volkerk (который говорит, что временные метки должны быть всегда основаны на UTC), верен, но если вам действительно нужен обходной путь (для создания временных меток на основе часового пояса), посмотрите на мой пример.

<?php

//default timezone
$date = new DateTime(null);
echo 'Default timezone: '.$date->getTimestamp().'<br />'."\r\n";

//America/New_York
$date = new DateTime(null, new DateTimeZone('America/New_York'));
echo 'America/New_York: '.$date->getTimestamp().'<br />'."\r\n";

//Europe/Amsterdam
$date = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
echo 'Europe/Amsterdam: '.$date->getTimestamp().'<br />'."\r\n";

echo 'WORK AROUND<br />'."\r\n";
// WORK AROUND
//default timezone
$date = new DateTime(null);
echo 'Default timezone: '.($date->getTimestamp() + $date->getOffset()).'<br />'."\r\n";

//America/New_York
$date = new DateTime(null, new DateTimeZone('America/New_York'));
echo 'America/New_York: '.($date->getTimestamp() + $date->getOffset()).'<br />'."\r\n";

//Europe/Amsterdam
$date = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
echo 'Europe/Amsterdam: '.($date->getTimestamp() + $date->getOffset()).'<br />'."\r\n";
?>

Получить обычную метку времени и добавить смещение UTC

21 голосов
/ 29 декабря 2011

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

Время Unix, или время POSIX, представляет собой систему для описания моментов во времени, определяемых как количество секунд, прошедших с полуночного координированного универсального времени (UTC) четверга, 1 января 1970 года

Отметка времени unix не зависит от настройки часового пояса. Установка часового пояса влияет только на интерпретацию значения метки времени.

2 голосов
/ 13 марта 2018

У меня была такая же проблема, и это самый простой подход, который я мог сделать довольно быстро.

$dateTimeZone = new DateTimeZone("America/New_York");
$dateTime = new DateTime("now", $dateTimeZone);
$timeOffset = $dateTimeZone->getOffset($dateTime);

// New time since epoch according to timezone
$newTime = time() + $timeOffset;

echo date("H:i:s", $newTime);
0 голосов
/ 11 июля 2019

Вот функция для конвертирования метки времени unix / gmt / utc в требуемый часовой пояс .

function unix_to_local($timestamp, $timezone){
    // Create datetime object with desired timezone
    $local_timezone = new DateTimeZone($timezone);
    $date_time = new DateTime('now', $local_timezone);
    $offset = $date_time->format('P'); // + 05:00

    // Convert offset to number of hours
    $offset = explode(':', $offset);
    if($offset[1] == 00){ $offset2 = ''; }
    if($offset[1] == 30){ $offset2 = .5; }
    if($offset[1] == 45){ $offset2 = .75; }
    $hours = $offset[0].$offset2 + 0;

    // Convert hours to seconds
    $seconds = $hours * 3600;

    // Add/Subtract number of seconds from given unix/gmt/utc timestamp
    $result = floor( $timestamp + $seconds );

    return $result;
}
0 голосов
/ 22 октября 2018

Увидел ответы с помощью решения смещения, и я думаю, что если вы не сэкономите время в базе данных в формате UTC или Unix, они не помогут. Проблема, когда дело доходит до getTimestamp (), заключается в том, что часовой пояс не учитывается, даже когда вы инициируете объект ... Как я могу это объяснить:) ... допустим, у вас есть какое-то событие с датой и временем в вашей базе данных , Вы также правильно настроили часовой пояс. Я добавлю их в vars для этого примера, чтобы он был более заметен:

$dateTime = '25.08.2018 16:45:15';//some event in your db //can be any valid format
$localTimezone = 'Europe/Berlin';
$dateTimeLocal = new \DateTime($dateTime, new \DateTimeZone($localTimezone));
var_dump($dateTimeLocal->getTimestamp());`

Теперь ... когда вы делаете это, вы передаете дату и время вашему конструктору. Вы ожидаете, что php будет уважать ваш часовой пояс, и вы получите метку времени UTC, соответствующую 16:45 в Берлине, что будет UTC 15:45 зимой и UTC 14:45 летом. Этого не произойдет - вы получите метку времени, соответствующую UTC 16:45. Если вы добавите смещение сейчас, у вас будет час или два.

Правильный способ сделать это - инициализировать объект, установить / переключить часовые пояса, создать форматированное время даты, которое учитывает часовой пояс, а затем получить метку времени из отформатированного времени даты. Это может быть немного медленнее, но это провал часового пояса доказать:

$date = '25.08.2018 16:45:15';//some event in your db //can be any valid format
$format = 'Y-m-d H:i:s';//just a format we will use for this example //also can be any valid format
$localTimezone = 'Europe/Berlin';
$remoteTimezone = 'America/Lima';
$dateTime = new \DateTime($date, new \DateTimeZone($localTimezone));
$dateTime->setTimezone(new \DateTimeZone($remoteTimezone));
$timestampLima = DateTime::createFromFormat($format, $dateTime->format($format))->getTimestamp();
...