PHP Conference Nagoya 2025

サポートする日付と時刻の書式

この節では DateTimeImmutable, DateTime, date_create_immutable(), date_create(), date_parse() および strtotime() が解釈可能な、全てのBNFライクな書式について説明します。 これらの書式はセクションごとにグループ分けされています。 たいていの場合、一つの日付・時刻文字列の中でホワイトスペース、 コンマまたはドットで区切られた異なるセクションの書式を併用することができます。 それぞれの書式について、説明と一緒に1個以上の例を示してあります。 シングルクォートで囲まれたフォーマットは大文字小文字を区別しません。 ('t't とも T とも書けます)。 ダブルクォートで囲まれたフォーマットは大文字小文字を区別します。 ("T"T としか書けません)。

DateTimeImmutableDateTime オブジェクトをフォーマットするには、 DateTimeInterface::format() のドキュメントを参照ください。

以下の一般的なルールを考慮すべきです。

  1. 日付/時刻のパーサーは、 個別の単位(年月日時分秒)ごとに許される値の範囲を持っています。 年については4桁の数値、 月については 0-12。 日は 0-31、 時 は 0-24。分は 0-59 の範囲を持ちます。
  2. 秒に60を入れても構いません。 なぜなら、うるう秒を含んだ日付の文字列が現れる場合があるからです。 しかし、PHP は "60" を不正な秒として扱う UnixTime を実装しているため、 60 を入れるとオーバーフローします。
  3. strtotime() は、 いずれかの数値が範囲外の場合に false を返します。 DateTimeImmutable::__construct() はその場合に例外をスローします。
  4. 文字列が日付の場合、時刻に関する全ての要素は 0 にリセットされます。
  5. 時刻の一部が指定された文字列に含まれている場合、 重要でない時刻の要素は全て0にリセットされます。
  6. 日付/時刻のパーサーはお馬鹿なので、 高速にするためのチェックは行いません (そのため、より汎用的です)。
  7. 個別の時刻フォーマット以外にも、 日付/時刻のパーサーは 複合的な書式 を理解します。たとえば Unixタイムスタンプ (@1690388256) や、ISO の週番号 (2008-W28-3) などです。
  8. 不正な日付を渡していないかどうかについて、追加のチェックが行われます:

    <?php
    $res
    = date_parse("2015-09-31");
    var_dump($res["warnings"]);
    ?>

    上の例の出力は以下となります。

    array(1) {
      [11] =>
      string(27) "The parsed date was invalid"
    }
    

  9. エッジケースも処理できます。 ただ、処理するためには、 DateTimeImmutable::createFromFormat() を使い、正しいフォーマットを指定する必要があります。

    <?php
    $res
    = DateTimeImmutable::createFromFormat("Y-m-d", "2015-09-34");
    var_dump($res);

    上の例の出力は以下となります。

    object(DateTimeImmutable)#1 (3) {
      ["date"]=>
      string(26) "2015-10-04 17:24:43.000000"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(13) "Europe/London"
    }
    

時刻の書式

このページでは、 DateTimeImmutable, DateTime, date_create(), date_create_immutable(), そして strtotime() のパーサーが理解する、 BNFライクな時刻フォーマットを説明します。

DateTimeImmutableDateTime オブジェクトをフォーマットするには、 DateTimeInterface::format() のドキュメントを参照ください。

シンボル一覧
シンボル 書式
frac . [0-9]+ ".21342", ".85"
hh "0"?[1-9] | "1"[0-2] "04", "7", "12"
HH [01][0-9] | "2"[0-4] "04", "07", "19"
meridian [AaPp] .? [Mm] .? [\0\t ] "A.m.", "pM", "am."
MM [0-5][0-9] "00", "12", "59"
II [0-5][0-9] "00", "12", "59"
space [ \t]  
tz "("? [A-Za-z]{1,6} ")"? | [A-Z][a-z]+([_/][A-Z][a-z]+)+ "CEST", "Europe/Amsterdam", "America/Indiana/Knox"
tzcorrection "GMT"? [+-] hh ":"? MM? "+0400", "GMT-07:00", "-07:00"
12時間制の表記
説明 書式
時、午前/午後 hh space? meridian "4 am", "5PM"
時、分、午前/午後 hh [.:] MM space? meridian "4:08 am", "7:19P.M."
時、分、秒、午前/午後 hh [.:] MM [.:] II space? meridian "4:08:37 am", "7:19:19P.M."
MS SQL (時、分、秒、端数、午前/午後) hh ":" MM ":" II [.:] [0-9]+ meridian "4:08:39:12313am"
24時間制の表記
説明 書式
時、分 't'? HH [.:] MM "04:08", "19.19", "T23:43"
時、分(コロンなし) 't'? HH MM "0408", "t1919", "T2343"
時、分、秒 't'? HH [.:] MM [.:] II "04.08.37", "t19:19:19"
時、分、秒(コロンなし) 't'? HH MM II "040837", "T191919"
時、分、秒、タイムゾーン 't'? HH [.:] MM [.:] II space? ( tzcorrection | tz ) "040837CEST", "T191919-0700"
時、分、秒、端数 't'? HH [.:] MM [.:] II frac "04.08.37.81412", "19:19:19.532453"
タイムゾーン tz | tzcorrection "CEST", "Europe/Amsterdam", "+0430", "GMT-06:00"

日付の書式

このページでは、 DateTimeImmutable, DateTime, date_create(), date_create_immutable() および strtotime() のパーサーが理解する、 BNFライクな日付フォーマットを説明します。

DateTimeImmutableDateTime オブジェクトをフォーマットするには、 DateTimeInterface::format() のドキュメントを参照ください。

シンボル一覧
シンボル 書式
daysuf "st" | "nd" | "rd" | "th"  
dd ([0-2]?[0-9] | "3"[01]) daysuf? "7th", "22nd", "31"
DD "0" [0-9] | [1-2][0-9] | "3" [01] "07", "31"
m 'january' | 'february' | 'march' | 'april' | 'may' | 'june' | 'july' | 'august' | 'september' | 'october' | 'november' | 'december' | 'jan' | 'feb' | 'mar' | 'apr' | 'may' | 'jun' | 'jul' | 'aug' | 'sep' | 'sept' | 'oct' | 'nov' | 'dec' | "I" | "II" | "III" | "IV" | "V" | "VI" | "VII" | "VIII" | "IX" | "X" | "XI" | "XII"  
M 'jan' | 'feb' | 'mar' | 'apr' | 'may' | 'jun' | 'jul' | 'aug' | 'sep' | 'sept' | 'oct' | 'nov' | 'dec'  
mm "0"? [0-9] | "1"[0-2] "0", "04", "7", "12"
MM "0" [0-9] | "1"[0-2] "00", "04", "07", "12"
y [0-9]{1,4} "00", "78", "08", "8", "2008"
yy [0-9]{2} "00", "08", "78"
YY [0-9]{4} "2000", "2008", "1978"
YYY [0-9]{5,19} "81412", "20192"
各国ごとの表記法
説明 書式
アメリカ式の月、日 mm "/" dd "5/12", "10/27"
アメリカ式の月、日、年 mm "/" dd "/" y "12/22/78", "1/17/2006", "1/17/6"
スラッシュで区切られた、4桁の年、月、日 YY "/" mm "/" dd "2008/6/30", "1978/12/22"
4桁の年、月 (GNU) YY "-" mm "2008-6", "2008-06", "1978-12"
ハイフンで区切られた、年、月、日 y "-" mm "-" dd "2008-6-30", "78-12-22", "8-6-21"
ドットかタブかハイフンで区切られた、日、月、4桁の年 dd [.\t-] mm [.-] YY "30-6-2008", "22.12.1978"
ドットかタブで区切られた、日、月、2桁の年 dd [.\t] mm "." yy "30.6.08", "22\t12.78"
日、月の文字表記、年 dd ([ \t.-])* m ([ \t.-])* y "30-June 2008", "22DEC78", "14 III 1879"
月の文字表記、4桁の年 (日は1日にリセットされる) m ([ \t.-])* YY "June 2008", "DEC1978", "March 1879"
4桁の年、月の文字表記 (日は1日にリセットされる) YY ([ \t.-])* m "2008 June", "1978-XII", "1879.MArCH"
月の文字表記、日、年 m ([ .\t-])* dd [,.stndrh\t ]+ y "July 1st, 2008", "April 17, 1790", "May.9,78"
月の文字表記、日 m ([ .\t-])* dd [,.stndrh\t ]* "July 1st,", "Apr 17", "May.9"
日、月の文字表記 dd ([ .\t-])* m "1 July", "17 Apr", "9.May"
月の省略形、日、年 M "-" DD "-" y "May-09-78", "Apr-17-1790"
年、月の省略形、日 y "-" M "-" DD "78-Dec-22", "1814-MAY-17"
年 (年だけの指定) YY "1978", "2008"
年 (拡張表記、5-19 桁。符号付き) [+-] YYY "-81120", "+20192"
月の文字表記 (月だけの指定) m "March", "jun", "DEC"
ISO 8601 に準拠した表記法
説明 書式
年、月、日の8桁 YY MM DD "15810726", "19780417", "18140517"
スラッシュで区切られた、4桁の年、月、日 YY "/" MM "/" DD "2008/06/30", "1978/12/22"
ハイフンで区切られた、2桁の年、月、日 yy "-" MM "-" DD "08-06-30", "78-12-22"
符号つきまたは符号なしの4桁の年、月、日 [+-]? YY "-" MM "-" DD "-0002-07-26", "+1978-04-17", "1814-05-17"
符号が必須。5桁の年、月、日 [+-] YYY "-" MM "-" DD "-81120-02-26", "+20192-04-17"

注意:

シンボル y または yy を含む書式について、 100未満の年は特別な扱いになります。年が0から69までの間だった場合、 2000を足した数になります。 また、年が70から99までの間だった場合、1900を足した数になります。 つまり、"00-01-01" は "2000-01-01" と解釈されます。

注意:

書式「ドットかタブで区切られた、日、月、2桁の年」 (dd [.\t] mm "." yy) は年が61から99の間のときだけ機能します。 この範囲外の年を与えた場合には 時刻の書式 の "HH [.:] MM [.:] SS" が優先されます。

注意:

書式「年 (年だけの指定)」は、時刻の指定が先に出現している場合のみ機能します。 そうでない場合、指定された4桁は HH MM とみなされます。

警告

シンボル ddDD について、 オーバーフローやアンダーフローすることができます。 つまり、 0 日は先月の最終日の意味になりますし、 オーバーフローすると翌月に繰り越しになります。 このルールにより、"2008-08-00" は "2008-07-31" と同一になり、 "2008-06-31" は "2008-07-01" と同一になります ( 6 月は 30 日までしかないので)。

「日」の範囲が 0 から 31 までに絞られていることに注意しましょう。 先ほどの正規表現が示すとおりです。 したがって、たとえば "2008-06-32" は日付文字列として妥当な形式ではなくなります。

また、シンボル mmMM についても 0 を用いてアンダーフローすることができます。 0 月は前年の 12 月を意味します。 たとえば "2008-00-22" は "2007-12-22" と同一です。

もしこれらを併用し、日も月もアンダーフローした場合は次のようになります。 "2008-00-00" は、まず "2007-12-00" へと変換され、 さらに "2007-11-30" へと変換されます。 文字列 "0000-00-00" についても同様に "-0001-11-30" へと変形されます。 (ISO 8601 における -1 年は、予測的グレゴリオ暦 (proleptic Gregorian calendar) で言うところの紀元前 2 年になります。)

複合的な書式

このページでは、 DateTimeImmutable, DateTime, date_create(), date_create_immutable() および strtotime() のパーサーが理解する、 BNFライクな日付/時刻 複合フォーマットを説明します。

DateTimeImmutableDateTime オブジェクトをフォーマットするには、 DateTimeInterface::format() のドキュメントを参照ください。

シンボル一覧
シンボル 書式
DD "0" [0-9] | [1-2][0-9] | "3" [01] "02", "12", "31"
doy "00"[1-9] | "0"[1-9][0-9] | [1-2][0-9][0-9] | "3"[0-5][0-9] | "36"[0-6] "001", "012", "180", "350", "366"
frac . [0-9]+ ".21342", ".85"
hh "0"?[1-9] | "1"[0-2] "04", "7", "12"
HH [01][0-9] | "2"[0-4] "04", "07", "19"
meridian [AaPp] .? [Mm] .? [\0\t ] "A.m.", "pM", "am."
ii [0-5]?[0-9] "04", "8", "59"
II [0-5][0-9] "04", "08", "59"
M 'jan' | 'feb' | 'mar' | 'apr' | 'may' | 'jun' | 'jul' | 'aug' | 'sep' | 'sept' | 'oct' | 'nov' | 'dec'  
MM [0-1][0-9] "00", "12"
space [ \t]  
ss ([0-5]?[0-9])|60 "04", "8", "59", "60" (うるう秒)
SS [0-5][0-9] "04", "08", "59"
W "0"[1-9] | [1-4][0-9] | "5"[0-3] "05", "17", "53"
tzcorrection "GMT"? [+-] hh ":"? II? "+0400", "GMT-07:00", "-07:00"
YY [0-9]{4} "2000", "2008", "1978"
標準のフォーマット
説明
ATOM "2022-06-02T16:58:35+00:00"
COOKIE "Thursday, 02-Jun-2022 16:58:35 UTC"
ISO8601 "2022-06-02T16:58:35+0000"
» RFC 822 "Thu, 02 Jun 22 16:58:35 +0000"
» RFC 850 "Thursday, 02-Jun-22 16:58:35 UTC"
» RFC 1036 "Thu, 02 Jun 22 16:58:35 +0000"
» RFC 1123 "Thu, 02 Jun 2022 16:58:35 +0000"
» RFC 2822 "Thu, 02 Jun 2022 16:58:35 +0000"
» RFC 3339 "2022-06-02T16:58:35+00:00"
» RFC 3339 Extended "2022-06-02T16:58:35.698+00:00"
» RFC 7231 "Thu, 02 Jun 2022 16:58:35 GMT"
RSS "Thu, 02 Jun 2022 16:58:35 +0000"
W3C "2022-06-02T16:58:35+00:00"
ローカライズされた表記法
説明 書式
Common Log Format dd "/" M "/" YY : HH ":" II ":" SS space tzcorrection "10/Oct/2000:13:55:36 -0700"
EXIF YY ":" MM ":" DD " " HH ":" II ":" SS "2008:08:07 18:11:31"
ISO の年、 ISO の週番号 YY "-"? "W" W "2008W27", "2008-W28"
ISO の年、 ISO の週番号、 ISO の曜日番号 YY "-"? "W" W "-"? [0-7] "2008W273", "2008-W28-3"
MySQL YY "-" MM "-" DD " " HH ":" II ":" SS "2008-08-07 18:11:31"
PostgreSQL: 年、日番号 YY "."? doy "2008.197", "2008197"
SOAP YY "-" MM "-" DD "T" HH ":" II ":" SS frac tzcorrection? "2008-07-01T22:35:17.02", "2008-07-01T22:35:17.03+08:00"
Unix タイムスタンプ "@" "-"? [0-9]+ "@1215282385"
マイクロ秒付きのUnix タイムスタンプ "@" "-"? [0-9]+ "." [0-9]{0,6} "@1607974647.503686"
XMLRPC YY MM DD "T" hh ":" II ":" SS "20080701T22:38:07", "20080701T9:38:07"
XMLRPC (短縮形) YY MM DD 't' hh II SS "20080701t223807", "20080701T093807"
WDDX YY "-" mm "-" dd "T" hh ":" ii ":" ss "2008-7-1T9:3:37"

注意:

書式「 ISO の年、 ISO の週番号」と 「 ISO の年、 ISO の週番号、 ISO の曜日番号」で使われている "W" は大文字小文字を区別します。大文字の "W" だけが利用できます。

「 SOAP 」、「 XMLRPC 」および「 WDDX 」の各書式中の "T" は大文字小文字を区別します。大文字の "T" だけが利用できます。

書式「 Unix タイムスタンプ 」は、タイムゾーンを UTC に設定します。

(訳注)書式「 Common Log Format 」は、 Apache ログにおける時刻の書式です。

(訳注)書式「 ISO の年、 ISO の週番号」と 「 ISO の年、 ISO の週番号、 ISO の曜日番号」は、 ISO 8601で規定されている表記法です。 定義上、週が前年あるいは翌年に属すことがあるので注意してください。 たとえば、 ISO 8601 の定義では 2010 年の第 1 週は 1 月 3 日から 1 月 9 日までとなり、 2010 年の 1 月 1 日と 1 月 2 日は 2009 年の第 53 週に属します。

相対的な書式

このページでは、 DateTimeImmutable, DateTime, date_create(), date_create_immutable(), そして strtotime() のパーサーが理解する、 BNFライクな相対日付/時刻フォーマットを説明します。

DateTimeImmutableDateTime オブジェクトをフォーマットするには、 DateTimeInterface::format() のドキュメントを参照ください。

シンボル一覧
シンボル 書式
dayname 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'
daytext 'weekday' | 'weekdays'
number [+-]?[0-9]+
ordinal 'first' | 'second' | 'third' | 'fourth' | 'fifth' | 'sixth' | 'seventh' | 'eighth' | 'ninth' | 'tenth' | 'eleventh' | 'twelfth' | 'next' | 'last' | 'previous' | 'this'
reltext 'next' | 'last' | 'previous' | 'this'
space [ \t]+
unit 'ms' | 'µs' | (( 'msec' | 'millisecond' | 'µsec' | 'microsecond' | 'usec' | 'sec' | 'second' | 'min' | 'minute' | 'hour' | 'day' | 'fortnight' | 'forthnight' | 'month' | 'year') 's'?) | 'weeks' | daytext
日付に基づいた表記
書式 説明
'yesterday' 昨日の00:00:00 "yesterday 14:00"
'midnight' 時刻を00:00:00にします  
'today' 時刻を00:00:00にします  
'now' 今 - 単に無視されます  
'noon' 時刻を12:00:00にします "yesterday noon"
'tomorrow' 明日の00:00:00  
'back of' hour 指定された時の15分後 "back of 7pm", "back of 15"
'front of' hour 指定された時の15分前 "front of 5am", "front of 23"
'first day of' 現在月の最初の日にします。 これは、現在月にしか影響しないため、 通常はこの書式に続けて月名を指定する使いかたが最適です。 "first day of January 2008"
'last day of' 現在月の最後の日にします。 これは、現在月にしか影響しないため、 通常はこの書式に続けて月名を指定する使いかたが最適です。 "last day of next month"
ordinal space dayname space 'of' 現在月のx番目の曜日を計算します。 "first sat of July 2008"
'last' space dayname space 'of' 現在月の 最後の 曜日を計算します。 "last sat of July 2008"
number space? (unit | 'week') 値を数値で指定するような、相対的な時間指定を処理します。 "+5 weeks", "12 day", "-7 weekdays"
(ordinal | reltext) space unit 値を英単語で指定するような、相対的な時間指定を処理します。 lastprevious は、-1 に等しく、this に等しいものはありません。そして next+1 に等しいです。 "fifth day", "second month", "last day", "previous year"
'ago' 直前に指定された相対的な時間指定について、正負反転します。 "2 days ago", "8 days ago 14:00", "2 months 5 days ago", "2 months ago 5 days", "2 days ago"
dayname 現在からみて次にやってくる、指定された曜日にします。(曜日指定についての注意 も参照ください) "Monday"
reltext space 'week' 特別な書式 "weekday + last/this/next week" を処理します。 "Monday next week"

注意:

相対的な記述は、相対的でない記述の 後で 処理されます。 このため、 "+1 week july 2008" と "july 2008 +1 week" とは同一になります。

ただし、 "yesterday"、 "midnight"、 "today"、 "noon" そして "tomorrow" はこのルールの例外です。 つまり、 "tomorrow 11:00" と "11:00 tomorrow" は異なります。 たとえば、今日が2008年7月23日だとしましょう。 このときの1つ目の結果は "2008-07-24 11:00" ですが、 2つ目の方は "2008-07-24 00:00" となります。 このような結果になる理由は、 これら5つの記述が現在時刻に直接影響するためです。

"first day of" のようなキーワードは、 相対的な書式文字列が使われるコンテクストに依存します。 static メソッドや関数で使われた場合、 参照されるのは現在のタイムスタンプですが、 DateTime::modify()DateTimeImmutable::modify() で使われた場合、参照されるのは modify() メソッドがコールされたオブジェクトです。

注意:

日付/時刻文字列中の曜日指定が現在の曜日と同じ場合は、 以下の点に注意してください。 この場合、日付文字列中の曜日は、曜日を明示的に指定しなかった場合に 日付文字列の相対的でない部分から計算される曜日と同一ではありますが、 指定しなくても同じというわけではありません。

  1. "dayname" は、 日付を進め ません 。 (例: "Wed July 23rd, 2008" は "2008-07-23" の意味です。)
  2. "number dayname" は、 日付を進めません 。 (例: "1 wednesday july 23rd, 2008" は "2008-07-23" の意味です。)
  3. "number week dayname" は、 指定された週を加算しますが、 さらに日付を進めることはしません。 この場合、"number week" と "dayname" は 2 つの別個のブロックとなります。 (例: "+1 week wednesday july 23rd, 2008" は "2008-07-30" の意味です。)
  4. "ordinal dayname" は、日付を別の日まで進めます。 (例: "first wednesday july 23rd, 2008" は "2008-07-30" の意味です。)
  5. "number week ordinal dayname" は、まず指定された週を加算し、 それから日付を別の日まで進めます。 この場合、 "number week" と "ordinal dayname" は2つの別個のブロックとなります。 (例: "+1 week first wednesday july 23rd, 2008" は "2008-08-06" の意味です。)
  6. "ordinal dayname 'of' " は日付を進め ません 。 (例: "first wednesday of july 23rd, 2008" は "2008-07-02" の意味です。 なぜなら、'of'を含む一連の語群 'first wednesday of july' が 相対的な書式として処理されることで 日付を同月の '1' 日にリセットしてしまい、'23rd' は無視されてしまうのです。)

また、書式 "ordinal space dayname space 'of' " と "'last' space dayname space 'of' " に含まれる "of" は少々特別扱いなので、注意してください。

  1. 日付を指定月の1日にします。
  2. "ordinal dayname 'of' " は日付を進め ません 。 (例: "first tuesday of july 2008" は "2008-07-01" の意味です。)
  3. "ordinal dayname " は日付を進め ます 。 (例: "first tuesday july 2008" は "2008-07-08" の意味です。上記の項番4を参照。)
  4. "'last' dayname 'of' " は、 指定された曜日(dayname)の同月最後の日を返します。 (例: "last wed of july 2008" は "2008-07-30" の意味です。)
  5. "'last' dayname" は、 現在日付からみて直前の、指定された曜日(dayname)を返します。 (例: "last wed july 2008" は "2008-06-25" の意味です。 まず "july 2008" を処理して現在日付を "2008-07-01" とみなし、 次に "last wed" により直前の水曜日、つまり "2008-06-25" へと移動します。)

注意:

月数を相対指定すると、その途中に経過する月の日数を使って結果を算出します。 たとえば "+2 month 2011-11-30" の結果は "2012-01-30" となります。 11 月の日数は 30 日、12 月の日数は 31 日なので、 その合計である 61 日後となるわけです。

注意:

number整数値 です。 つまり、小数値が与えられると、ドット(またはコンマ) はデリミタとして解釈されがちです。 たとえば、'+1.5 hours''+1 hour +30 minutes' ではなく '+1 5 hours' のようにパースされます。

変更履歴

バージョン 説明
8.2.0 number シンボルは、複数の符号を受け入れなくなりました。 たとえば、+-2 のようなフォーマットです。
7.0.8 週の始まりが常に月曜日となりました。 これより前のバージョンでは、日曜日も週の始まりとみなされていました。

add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top