web-dev-qa-db-ja.com

タイムゾーンに基づいてPHPでUnixタイムスタンプを取得する方法

最初にコード

    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タイムスタンプを出力するにはどうすればよいですか?

17
jimy

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オフセットを追加する

31
Cecil Zorg

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

Unix時間、またはPOSIX時間は、経過した秒数として定義された、瞬間を表すシステムです。 午前0時から協定世界時(UTC) 1970年1月1日木曜日

UNIXタイムスタンプはタイムゾーン設定の影響を受けません。タイムゾーンの設定は、タイムスタンプ値の解釈にのみ影響します。

21
VolkerK

私自身も同じ問題を抱えていましたが、これはかなり迅速に実行できる最も簡単なアプローチです。

$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);
2
dalslandan200

オフセットソリューションで答えを見たところ、UTCまたはUnixタイムスタンプのデータベースに時間を保存しない限り、役に立たないと思います。 getTimestamp()に関する問題は、オブジェクトを開始してもタイムゾーンが考慮されないことです...どのように説明すればよいですか:)... dbに日付と時刻のあるイベントがあるとしましょう。また、タイムゾーンが正しく設定されています。この例では、これらを変数に入れて、より見やすくします。

$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があなたのタイムゾーンを尊重し、ベルリンでは16:45に対応するUTCタイムスタンプを取得するということです。それは起こりません-あなたが得るのはUTC 16:45に対応するタイムスタンプです。ここでオフセットを追加すると、1〜2時間ずれます。

これを行う正しい方法は、オブジェクトを開始し、タイムゾーンを設定/切り替え、タイムゾーンを尊重するフォーマットされた日時を作成し、フォーマットされた日時からタイムスタンプを取得することです。少し遅いかもしれませんが、タイムゾーンは失敗を証明します:

$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();
0
Iliya Kolev

これは、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
MR_AMDEV