支持的日期和时间格式

本节以 BNF 类似的格式描述了 DateTimeImmutableDateTimedate_create_immutable()date_create()date_parse()strtotime() 解析器可以理解的所有不同格式。格式按部分分组。在大多数情况下,来自不同部分的格式,通过空格、逗号或点分隔,可以在同一个日期/时间字符串中使用。对于每个支持的格式,都会给出示例和格式说明。格式中用单引号括起来的字符不区分大小写('t' 可以是 tT),用双引号括起来的字符区分大小写("T" 只能是 T)。

要格式化 DateTimeImmutableDateTime 对象,请参阅 DateTimeInterface::format() 方法的文档。

应该考虑一组通用的规则。

  1. 解析器允许每个单位(年、月、日、时、分、秒)具有完整的取值范围。对于年,就是 4 位数字,对于月,就是 0-12,对于日,就是 0-31,对于时,就是 0-24,对于分,就是 0-59。
  2. 秒允许 60,因为有时包含闰秒的日期字符串会出现。但是 PHP 实现的是 Unix 时间,其中 "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"
    }
    

时间格式

本页以 BNF 类似的语法描述了 DateTimeImmutableDateTimedate_create()date_create_immutable()strtotime() 解析器可以理解的不同日期/时间格式。

要格式化 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"

日期格式

本页以 BNF 类似的语法描述了 DateTimeImmutableDateTimedate_create()date_create_immutable()strtotime() 解析器可以理解的不同日期格式。

要格式化 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 年 6 月", "1978 年 12 月", "1879 年 3 月"
文本格式的月、日和年 m ([ .\t-])* dd [,.stndrh\t ]+ y "2008 年 7 月 1 日", "1790 年 4 月 17 日", "78 年 5 月 9 日"
文本格式的月和日 m ([ .\t-])* dd [,.stndrh\t ]* "7 月 1 日", "4 月 17 日", "5 月 9 日"
日和文本格式的月 dd ([ .\t-])* m "1 月", "17 月", "9 月"
月缩写、日和年 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 "3 月", "6 月", "12 月"
ISO8601 格式
描述 格式 示例
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"

注意:

对于 yyy 格式,当使用 yyy 符号时,小于 100 的年份会以特殊方式处理。如果年份在 0(包含)到 69(包含)之间,则添加 2000。如果年份在 70(包含)到 99(包含)之间,则添加 1900。这意味着 "00-01-01" 将被解释为 "2000-01-01"。

注意:

"日,月和两位数的年,用点或制表符分隔" 格式 (dd [.\t] mm "." yy) 仅适用于年份值在 61(包含)到 99(包含)之间 - 在这些年份之外,时间格式 "HH [.:] MM [.:] SS" 优先。

注意:

"年(仅年)" 格式仅在已经找到时间字符串时才有效 - 否则该格式将被识别为 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,对应于公元前 2 年的儒略历)。

复合格式

本页以 BNF 类似语法描述了 DateTimeImmutableDateTimedate_create()date_create_immutable()strtotime() 解析器所理解的不同复合日期/时间格式。

要格式化 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 扩展 "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"
本地化表示法
描述 格式 示例
通用日志格式 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 周数和星期几 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 周数和星期几" 格式中的 "W" 区分大小写,只能使用大写 "W"。

SOAP、XMLRPC 和 WDDX 格式中的 "T" 区分大小写,只能使用大写 "T"。

"Unix 时间戳" 格式将时区设置为 UTC。

相对格式

本页以 BNF 类似语法描述了 DateTimeImmutableDateTimedate_create()date_create_immutable()strtotime() 解析器所理解的不同相对日期/时间格式。

要格式化 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' 昨天的午夜 "yesterday 14:00"
'midnight' 时间设置为 00:00:00  
'today' 时间设置为 00:00:00  
'now' 现在 - 忽略此项  
'noon' 时间设置为 12:00:00 "yesterday noon"
'tomorrow' 明天的午夜  
'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 等效于 -1this 等效于空, 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' 处理特殊格式 "星期几 + 上/这/下周"。 "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 日",第一个会生成 "2008-07-24 11:00",而第二个会生成 "2008-07-24 00:00"。这是因为这五个语句会直接影响当前时间。

诸如 "first day of" 这样的关键字取决于使用相对格式字符串的上下文。如果与静态方法或函数一起使用,则引用对象是当前系统时间戳。但是,如果在 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" 是两个不同的块。(例如:"+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" 是两个不同的块。(例如:"+1 week first wednesday july 23rd, 2008" 表示 "2008-08-06")。
  6. "ordinal dayname 'of' " 不会提前到另一天。(例如:"first wednesday of july 23rd, 2008" 表示 "2008-07-02",因为包含 'of' 的特定短语会将日重置为 '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 5 hours',而不是 '+1 hour +30 minutes'

变更日志

版本 描述
8.2.0 number 不再接受多个符号,例如 +-2
7.0.8 周始终从星期一开始。以前,星期日也被认为是周的开始。

添加注释

用户贡献的注释

此页面没有用户贡献的注释。
To Top