LoginSignup
0
0

More than 1 year has passed since last update.

【PHP】サマータイムかどうかを判定する

Posted at

目的

サマータイムのある地域において、特定の日付がサマータイムの期間内かどうかを調べる機会があったので、PHPで判定の実装をしてみました。

結論

DateTimeZone::getTransitionsを用いて判定を行います。

$timezone = new DateTimeZone('America/Los_Angeles');
$datetime = new DateTime('2022/3/12', $timezone);
$transitions = $tz->getTransitions($datetime->getTimestamp(), $datetime->getTimestamp());
echo $transitions[0]['isdst']; // false

DateTimeZoneオブジェクト

PHPの日付クラスであるDateTimeはタイムゾーンの情報は持っていますが、サマータイムの情報はもっていません。
与えられた日時においてサマータイムかを判定するためにDateTimeZone::getTransitionsを使用しました。

getTransitionsメソッドは与えられたUnixタイムスタンプの期間内において、そのタイムゾーンの推移を取得することができます。

キー 説明
ts int Unixタイムスタンプ
time string DateTimeInterface::ISO8601 形式の文字列
offset int UTC からのオフセット(秒単位)
isdst bool サマータイムが有効かどうか
abbr string タイムゾーンの省略形

たとえばロサンゼルスでは、2022/1/1〜12/31の期間の推移を調べてみましょう。

$timezone = new DateTimeZone('America/Los_Angeles');
$timezone->getTransitions(strtotime('2022/1/1'), strtotime('2022/12/31'))

2022/3/13にサマータイムが開始され(PDT: 米国太平洋標準時(夏時間)になる)、2022/11/6にサマータイムが終了することがわかります(PST: 米国太平洋標準時になる)。

   [
     [
       "ts" => 1640962800,
       "time" => "2021-12-31T15:00:00+0000",
       "offset" => -28800,
       "isdst" => false,
       "abbr" => "PST",
     ],
     [
       "ts" => 1647165600,
       "time" => "2022-03-13T10:00:00+0000",
       "offset" => -25200,
       "isdst" => true,
       "abbr" => "PDT",
     ],
     [
       "ts" => 1667725200,
       "time" => "2022-11-06T09:00:00+0000",
       "offset" => -28800,
       "isdst" => false,
       "abbr" => "PST",
     ],
   ]

このとき、startとendを同一日時にしてやることでその時点においてサマータイムが適用されているかをisdistで調べてやることができます。

$timezone->getTransitions(strtotime('2022/1/1'), strtotime('2022/1/1')); // startとendを一致させる
[
     [
       "ts" => 1640962800,
       "time" => "2021-12-31T15:00:00+0000",
       "offset" => -28800,
       "isdst" => false,
       "abbr" => "PST",
     ],
   ]

注意

サマータイムの切り替え日における判定

サマータイムの切り替えタイミングでは意図していない挙動になる可能性があります。

たとえばロサンゼルスでは2022/11/6 2:00にサマータイムが終了し、また1:00に巻き戻す処理が行われます。
つまり2022/11/6 1:00〜2:00が2回存在し、サマータイムである状態とそうでない状態のどちらも両立するということです。

$timezone = new DateTimeZone('America/Los_Angeles');
$datetime = new DateTime('2022/11/6 1:00', $timezone);
$timezone->getTransitions($datetime->getTimestamp(), $datetime->getTimestamp());

この場合、結果はサマータイムになります。

[
     [
       "ts" => 1667721600,
       "time" => "2022-11-06T08:00:00+0000",
       "offset" => -25200,
       "isdst" => true,
       "abbr" => "PDT",
     ],
   ]

判定可能日時

getTransitionsで取得可能な期間は2037年までですので、それ以降の判定にもちいることはできません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0