PHPでのタイムゾーンの扱いとUTC保存の指針

タイムゾーンとは日付時刻がどの地域の時刻かを表す情報です。PHPではDateTimeZoneやデフォルト設定で扱い、保存はUTC・表示はローカルに統一するのが基本です。

まずデフォルトタイムゾーンを固定する

タイムゾーンを意識せずに date や DateTime を使うと、サーバー設定に引きずられて環境ごとに結果が変わる、という厄介な事態になります。まずはアプリの入口で明示的に固定しておくのが基本ですね。php.ini でも設定できますが、コード側で宣言しておくと環境依存を減らせます。

date_default_timezone_set('Asia/Tokyo');
echo date('Y-m-d H:i'); // 日本時間で出力される

DateTimeにはDateTimeZoneを渡す

DateTime 系はコンストラクタの第二引数で個別にタイムゾーンを指定できます。デフォルト設定に頼らず、そのオブジェクトが何時圏なのかをはっきりさせられるのがいいところですね。setTimezone で表示だけ別のゾーンに変換することもできます。

$utc = new DateTimeImmutable('2026-07-22 00:00', new DateTimeZone('UTC'));
$jst = $utc->setTimezone(new DateTimeZone('Asia/Tokyo'));
echo $utc->format('Y-m-d H:i'); // 2026-07-22 00:00
echo $jst->format('Y-m-d H:i'); // 2026-07-22 09:00(+9時間)

同じ瞬間を指しているのに表示が変わるだけ、という点がポイントです。内部の絶対時刻は変わっていません。

保存はUTC、表示でローカルに変換

複数のタイムゾーンにまたがるサービスでは、DB には UTC で保存し、表示のときにユーザーのタイムゾーンへ変換する、という方針が扱いやすいと思います。基準を一つに固めておけば、サマータイムや地域差の計算がぶれません。

// 保存時:ローカル入力をUTCに正規化して保存
$input = new DateTimeImmutable('2026-07-22 09:00', new DateTimeZone('Asia/Tokyo'));
$forDb = $input->setTimezone(new DateTimeZone('UTC'));
$sql = $forDb->format('Y-m-d H:i:s'); // 2026-07-21 24:00 → 00:00 UTC

// 表示時:UTCから読み出してローカルへ
$fromDb = new DateTimeImmutable('2026-07-22 00:00', new DateTimeZone('UTC'));
echo $fromDb->setTimezone(new DateTimeZone('Asia/Tokyo'))->format('Y-m-d H:i');

まとめ

タイムゾーンは「保存は UTC で統一、表示のときだけローカルに変換」という原則を守ると、後々の混乱がだいぶ減ると思います。DateTime を作るときは面倒でも DateTimeZone を明示して、暗黙のサーバー設定に依存しないようにしておくのが安全ですね。地域名は ‘Asia/Tokyo’ のような IANA 名で指定するのが確実です。

よくある質問

Q. まず何を設定すればいいですか?
A. アプリの入口でdate_default_timezone_setを呼び、デフォルトタイムゾーンを固定しておくと環境依存を減らせます。

Q. setTimezoneを呼ぶと時刻がずれますか?
A. 内部の絶対時刻は変わらず、表示だけが変換されます。同じ瞬間を別の地域の表記で見せているだけです。

Q. DBには何時圏で保存すべきですか?
A. UTCで統一して保存し、表示のときにユーザーのローカルへ変換する方針が扱いやすいです。

類似投稿

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です