LoginSignup
11
8

More than 5 years have passed since last update.

PHP で世界の日の出、日の入り時刻表を作る

Posted at

はじめに

PHP で世界の日の出、日の入り時刻表を作ってみました。
タイムゾーン、開始日、間隔、終了日を設定すれば、その期間の日の出、日の入り時刻表が表示される感じです。

サンプルコード

SunriseSunsetList.php
<?php
$timeZone = 'Asia/Tokyo';
// $timeZone = 'America/New_York';
// $timeZone = 'Europe/Oslo';

$period = new DatePeriod(
    date_create('first day of this month', timezone_open($timeZone)),
    new DateInterval('P1D'),
    date_create('last day of this month +1 second', timezone_open($timeZone))
);

$location = timezone_open($timeZone)->getLocation();
printf('%10s%9s%8s' . PHP_EOL, 'date', 'sunrise', 'sunset');

foreach ($period as $day) {
    $sunInfo = date_sun_info(
        $day->getTimeStamp(),
        $location['latitude'],
        $location['longitude']
    );

    printf('%s%9s%8s' . PHP_EOL,
        $day->format('Y-m-d'),
        $day->setTimeStamp($sunInfo['sunrise'])->format('H:i'),
        $day->setTimeStamp($sunInfo['sunset'])->format('H:i')
    );
}

まずはじめに日の出、日の入り時刻を調べたい都市のタイムゾーンを $timeZone に代入。
サポートされるタイムゾーンのリスト から、いろいろな都市のタイムゾーンを選ぶことができる。

DatePeriod::__construct では、開始日、間隔、終了日を設定。DateInterval::__construct の値を変えることによって、特定の月の時刻表や、一年を通して各月初めの時刻表など、さまざまな間隔での日の出、日の入り時刻表を作成できる。

AboutDateInterval.php
// period を表す P を最初につける
new DateInterval('P1D'); // 一日ごと
new DateInterval('P2W'); // 二週間ごと
new DateInterval('P3M'); // 三ヶ月ごと

// 時間を含む場合は、時間部分の前に文字 T を入れる
new DateInterval('PT1H'); // 一時間ごと
new DateInterval('PT1M'); // 一分ごと

DateTimeZone::getLocation では、タイムゾーンの位置情報 (国コード、緯度/経度、コメント) が取得できるので、この値を使って日の出、日の入り時刻を計算する。

今回のサンプルコードでは date_sun_info という関数を利用した。日の出時刻だけや、日の入り時刻だけ取得したい場合などは date_sunrise, date_sunset という関数でもよさそう。date_sun_info ではタイムスタンプ、緯度、経度を指定する。すると日の出、日の入り時刻などさまざまな情報がタイムスタンプとして配列で返ってくるので、あとはその値をいい感じにフォーマットして表示する。

以下は、東京の 2014-04-01 から 2014-04-30 まで一日ごとの日の出、日の入り時刻表になる。

$ php SunriseSunsetList.php
      date  sunrise  sunset
2014-04-01    05:27   18:02
2014-04-02    05:26   18:03
2014-04-03    05:24   18:03
(省略)
2014-04-28    04:52   18:24
2014-04-29    04:51   18:25
2014-04-30    04:50   18:26

例えば、ノルウェーの首都オスロのタイムゾーンで 2014-01 から 2014-12 まで各月初めの日の出、日の入り時刻表を表示したい場合は以下のようにする。

SunriseSunsetList.php
<?php
$timeZone = 'Europe/Oslo';

$period = new DatePeriod(
    date_create('2014-01', timezone_open($timeZone)),
    new DateInterval('P1M'),
    date_create('2014-12 +1 second', timezone_open($timeZone))
);

結果は以下。

$ php SunriseSunsetList.php
      date  sunrise  sunset
2014-01-01    09:18   15:23
2014-02-01    08:29   16:31
2014-03-01    07:14   17:44
2014-04-01    06:41   20:00
2014-05-01    05:14   21:13
2014-06-01    04:06   22:23
2014-07-01    04:00   22:41
2014-08-01    04:58   21:47
2014-09-01    06:12   20:21
2014-10-01    07:22   18:50
2014-11-01    07:39   16:22
2014-12-01    08:51   15:20

東京とはかなり違いますね。
ちなみに、南極のどこかのタイムゾーンにすると sunrise, sunset ともに同じ値になる日がある。
おそらく白夜かなとか、勝手に思ってます。

照らし合わせ

一応、本当に合っているかチェックするために、日の出日の入り(世界地名選択) で計算されたものと照らし合わせると、一致している、もしくは 1, 2 分の誤差が発生する程度でした。

備考

date_createDateTime::__construct
timezone_openDateTimeZone::__construct の別名です。

AboutDateTimeAlias.php
<?php
// 別名を使うことによって一行で日時が表示できるなどの利点があったり、
// PHP 5.2 もしくは 5.3 でも動作させることができる
echo date_create()->format('Y-m-d') . PHP_EOL;

// 以下でも上記と同じことができるが PHP 5.4 以降でしか動作しない
echo (new DateTime)->format('Y-m-d') . PHP_EOL;

また、今回のサンプルコードでは、タイムゾーンから緯度/経度を取得しているが、
もう少し細かく都市などを指定したい場合は、どこかから緯度/経度を引っ張ってきてやる必要が出てくる。

参考リンク

11
8
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
11
8