date — 日付/時刻を書式化して文字列にする

PHP
  • カテゴリ: PHP
  • 掲載バージョン: PHP 8.4
  • 名前空間 / FQCN / コマンド: date(string $format, ?int $timestamp = null): string|false
  • 関連: DateTimeImmutable::format / strtotime / time / gmdate / date_default_timezone_set / IntlDateFormatter
  • 変更履歴: PHP 8.1 以降、関連の strftime() が非推奨。date() 本体の仕様は大きな変更なし。

要点(TL;DR)

  • UNIXタイムスタンプを指定のフォーマット文字で整形して返す。
  • 最低限: echo date('Y-m-d H:i:s');
  • 罠:
    • タイムゾーン未設定で警告/期待しない時刻になる
    • m(月)とi(分)、H(24時)とh(12時)の取り違え
    • ミリ秒のまま渡して 1970-01-01 になる(ms→s 変換漏れ)

概要

date() は現在時刻または指定した UNIX タイムスタンプを、Y-m-d H:i:s のようなフォーマットで文字列化します。画面表示、ログファイル名、HTTP ヘッダ生成など、人間向けの固定フォーマット文字列が必要な場面で使います。ロケール依存の月名/曜日名が必要なら IntlDateFormatter を検討します。

構文 / シグネチャ

string|false date(string $format, ?int $timestamp = null)
  • 引数(表)
引数必須既定値説明
$formatstringはい書式指定(例 Y-m-d H:i:scr など)。不明な文字はそのまま出力。
$timestampint|nullいいえnullUNIX秒。null なら現在時刻。
  • 戻り値string(整形済み文字列)。範囲外のタイムスタンプなどでごくまれに false
  • 例外/副作用
    • 例外は投げません。
    • タイムゾーン未設定時に警告(E_WARNING)や期待外の時刻になることあり。
    • 32bit 環境では 2038 年問題の影響で範囲制限。

使用例

最小例

<?php
declare(strict_types=1);

date_default_timezone_set('Asia/Tokyo'); // 明示推奨

echo date('Y-m-d H:i:s'); // 例: 2025-09-08 09:41:23

実務例:日次ローテートのログファイル名+HTTPヘッダ

<?php
declare(strict_types=1);

date_default_timezone_set('Asia/Tokyo');

// 日次ローテート用ファイル名
$logPath = __DIR__ . '/logs/app-' . date('Y-m-d') . '.log';

// UTC の Last-Modified ヘッダ(HTTPはUTCが基本)
$lastModified = gmdate('D, d M Y H:i:s') . ' GMT';
header('Last-Modified: ' . $lastModified);

// 文字列→時刻の解釈と併用(ユーザー入力など)
$input = '2025-10-01 10:30';
$ts = strtotime($input);        // 失敗時は false
if ($ts !== false) {
    echo date('c', $ts);        // ISO 8601: 2025-10-01T10:30:00+09:00
}

(例外処理を伴う堅牢案:ユーザー指定のタイムゾーンを検証してから date_default_timezone_set、あるいは DateTimeImmutable + ->format() を使用)

よくある落とし穴・注意

  • タイムゾーンdate_default_timezone_set() または php.inidate.timezone を設定。未設定だと警告や意図しない時刻に。
  • 書式指定の取り違え
    • m=月(01–12) / i=分(00–59)
    • H=24時 / h=12時(a/Aと併用)
  • ミリ秒誤用:JSの Date.now()ミリ秒。PHPの date()intval($ms/1000) にする。
  • DST(夏時間):ローカル時刻での 1時間欠落/重複に注意。UTC基準にしたい場面は gmdate() を使う。
  • 32bit PHP:タイムスタンプ範囲が狭い(おおむね 1901–2038)。64bit または DateTimeImmutable を。
  • ロケール表記:月名・曜日名の日本語化は date() では不可。IntlDateFormatter を使う。
  • エラー形態:警告(E_WARNING)発生あり/戻り値 false になる可能性あり(型宣言は考慮)。

PHP 8.1–8.4 差分メモ

  • 8.1:strftime() 非推奨(ロケール表記には IntlDateFormatter 推奨)
  • 8.2–8.4:date() 仕様の大きな変更はなし(タイムゾーンDB更新は随時)

代替・関連APIとの比較

  • DateTimeImmutable::format():明示的な DateTimeZone と組み合わせてテストしやすい/安全。新規実装ではこちら推奨。
  • gmdate():常に UTC。HTTP ヘッダや署名用に。
  • IntlDateFormatter(ext-intl):ロケールに応じた「月/曜日名」の多言語表記。UI向け。
  • Carbon(Laravel):連鎖的操作・人間可読(diffForHumans)。内部は DateTime 系。

テスト例(Pest)

<?php

it('formats a given timestamp deterministically', function () {
    date_default_timezone_set('UTC');

    expect(date('Y-m-d', 0))->toBe('1970-01-01');
    expect(date('H:i', 3600))->toBe('01:00'); // 1970-01-01 01:00:00 UTC
});

トラブルシュート(エラー別)

症状/エラー原因対処
Warning: date(): It is not safe to rely on the system's timezone settings.タイムゾーン未設定date_default_timezone_set('Asia/Tokyo') または php.inidate.timezone を設定
表示が 1970-01-01 になるミリ秒をそのまま渡したintval($ms/1000) に変換
月と分を取り違えた表示mi の混同フォーマットを見直し(分は i
日本語の曜日・月名にできないdate() はロケール非対応IntlDateFormatter を使用
古い日付/遠い未来で失敗32bit PHP の範囲外64bit PHP / DateTimeImmutable を使用

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする