2016-10-30 14 views
1

したがって、ここにシナリオがあります:イベントの相対時間

私のアプリケーションにはトランザクションセクションがあります。アクションを記録し、その時間をUNIXタイムスタンプ(UTC)として保管します。

昨日私は£100.00を支払った。これは1477762205のUNIXタイムスタンプでデータベースに記録された。土曜日は2016年10月29日17:30:05 UTC/GMT。

(PHPで書かれた)

私のアプリケーションdatetimeオブジェクトを使用して、出力のタイムゾーン(ヨーロッパ/ロンドン)に渡して出力する(これは私のために午後07時30分現地時間です)。

昨日、19時30分に現地時間が正しく出力され、今日の午前2時に時計時刻が変更されたため、18時30分になります。

これは技術的には正しいですが、最初にトランザクションをログに記録するときのイベントの相対的な位置を覚えていれば、19時30分現地時間であることを覚えていれば正しく表示されなくなります。

私の質問は、イベントに対してUTCから時間を出力する最も良い方法は何ですか?ログが発生した時点のタイムゾーンを判断するために、UTCログを使用してタイムゾーンを保存する必要がありますか?

コード:

ログを保存:

(これは私が作成していロガークラスの一部である)

if($dateTime == null) { 

     $dateTime = time(); 

    } 

    $query = "INSERT INTO `".$this->databaseName."`.`log`(`datetime`,`action`) VALUES(?, ?);"; 
    if(!$stmt = $this->database->prepare($query)) { 

     return $this->database->error; 

    } 

    $stmt->bind_param('ss',$dateTime,$action); 

    $stmt->execute(); 

これを出力:

$dateTime = new DateTime(null, new DateTimeZone('UTC')); 
$dateTime->setTimestamp($log->timeStamp); 
$dateTime->setTimezone(new DateTimeZone('Europe/London')); 
echo $dateTime->format('d/m/Y H:i'); 

技術的に正しい出力:29/10/2016 18:30

しかし、実際のタイムスタンプに対してDSTを認識していることを表示することを願っています。

だから私は出力にそれを望む:すべての29/10/2016 19時30

+0

UTC Unixのタイムスタンプはどういう意味ですか? –

+0

非常に明確ではないので、意味の例を表示できますか? – vascowhite

+0

さて、29日の19:30イギリス時間で、私はトランザクションを記録しました。 PHPのページに出力するとき:$ datetime = new DateTime(null、new DateTimeZone( 'UTC'); $ datetime-> setTimestamp($ timeStamp); echo $ datetime-> format(これはUNIXのタイムスタンプは1477762205でした。 $フォーマット); 前30thヨーロッパ/ロンドンの場合は1930として表示されますが、投稿30日後は1830として表示されます19:30と表示されますPHPがDSTを認識していないようですか? – DanTheDJ1

答えて

1

まずは、1477762205 Unixタイムスタンプのために期待されるローカル値をまとめてみましょう:

  • UTC:17: 30:05(UTC、0000)
  • ロンドン:午前18時30分05秒(BST、3600別名0100、DST = 1)
  • マドリード:午後07時30分05秒(CEST、7200別名0200、DST = 1)

スタッフは、限り、あなたは都市ベースのタイムゾーン識別子を使用して期待通りに動作するようです:

foreach (['UTC', 'Europe/London', 'Europe/Madrid'] as $time_zone_id) { 
    $dt = new DateTime('@1477762205'); 
    $tz = new DateTimeZone($time_zone_id); 
    $dt->setTimezone($tz); 
    echo $time_zone_id . ': ' . $dt->format('H:i:s [e=T, O]') . PHP_EOL; 
} 
UTC: 17:30:05 [UTC=UTC, +0000] 
Europe/London: 18:30:05 [Europe/London=BST, +0100] 
Europe/Madrid: 19:30:05 [Europe/Madrid=CEST, +0200] 

やいなや私たちは、名前のゾーンの頭字語を使用して、奇妙なことが起こる:

foreach (['UTC', 'BST', 'GMT', 'CEST', 'CET'] as $time_zone_id) { 
    $dt = new DateTime('@1477762205'); 
    $tz = new DateTimeZone($time_zone_id); 
    $dt->setTimezone($tz); 
    echo $time_zone_id . ': ' . $dt->format('H:i:s [e=T, O]') . PHP_EOL; 
} 
UTC: 17:30:05 [UTC=UTC, +0000] 
BST: 17:30:05 [BST=BST, +0000] 
GMT: 17:30:05 [GMT=GMT, +0000] 
CEST: 18:30:05 [CEST=CEST, +0100] 
CET: 18:30:05 [CET=CET, +0100] 

があります基礎となるデータベースで利用可能なタイムゾーンの遷移に関する情報(またはその欠如)と、おそらくいくつかの関係:

$dt = new DateTime('@1477762205'); 
foreach (['UTC', 'BST', 'Europe/London', 'CEST', 'Europe/Madrid'] as $time_zone_id) { 
    $tz = new DateTimeZone($time_zone_id); 
    $dt->setTimezone($tz); 
    echo $time_zone_id . PHP_EOL; 
    echo '- Time zone offset: ' . $tz->getOffset($dt) . ' seconds' . PHP_EOL; 

    $transitions = $tz->getTransitions(mktime(0, 0, 0, 1, 1, 2016), mktime(0, 0, 0, 12, 31, 2016)); 
    if ($transitions===false) { 
     echo '- Error fetching transitions' . PHP_EOL; 
    } else { 
     echo '- ' . count($transitions) . ' transitions found' . PHP_EOL; 
    } 
} 
UTC 
- Time zone offset: 0 seconds 
- 1 transitions found 
BST 
- Time zone offset: 0 seconds 
- Error fetching transitions 
Europe/London 
- Time zone offset: 3600 seconds 
- 3 transitions found 
CEST 
- Time zone offset: 3600 seconds 
- Error fetching transitions 
Europe/Madrid 
- Time zone offset: 7200 seconds 
- 3 transitions found 

それはプレーンなバグですどのくらいの本の言うことは本当に難しいとカウンターどのくらいです直感的ではあるが、文書化されている。 PHPバグデータベースはで混雑しています。のエントリは間違いですが、DSTの境界を含む日付の計算では奇妙ではあるが実際のバグを個人的に見つけました。

+0

問題は変換されます。私はnullとdatetimezone utcでdatetimeを構築し、タイムスタンプを設定する場合、私はUTC時間を取得します。しかし、私は昨日のヨーロッパ/ロンドン時間に変換する必要がありますが、私はsetTimezoneヨーロッパ/ロンドン実際のタイムスタンプがあったときではなく、今日のものに変換されます。私は明確ではない場合は申し訳ありません夏時間を考慮していないようです – DanTheDJ1

+0

いいえ私はPHPのtim e()メソッド。 – DanTheDJ1

+0

Techincally私は正しい結果を得るが、私はタイムスタンプ後1秒を表示していたかのように、変換された時間を表示したい。したがって、DSTが英国の時間から削除された日付の前にタイムスタンプにDSTが適用されるようにします。したがって、このタイムスタンプのUTCが今日のタイムゾーンで正しい場合でも、私はPHPがDSTを意識していることを願っています。そのため、現在の日付ではなく、特定の時点での変換が何であるかに基づいて、 。 – DanTheDJ1

関連する問題