1
0
mirror of https://github.com/php/doc-en.git synced 2026-03-23 23:32:18 +01:00
Files
archived-doc-en/reference/datetime/formats.xml
AllenJB 3a8c3e77df Enable runnable (WASM) examples for datetime (#4887)
* Enable runnable (WASM) examples for datetime
2025-10-31 10:32:20 +00:00

1256 lines
42 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<chapter xml:id="datetime.formats" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Supported Date and Time Formats</title>
<para>
This section describes all the different formats in a BNF-like format, that the
<classname>DateTimeImmutable</classname>, <classname>DateTime</classname>,
<function>date_create_immutable</function>,
<function>date_create</function>, <function>date_parse</function>, and
<function>strtotime</function> parser understands. The formats are grouped
by section. In most cases formats from different sections, separated by
whitespace, comma or dot, can be used in the same date/time string. For each
of the supported formats, one or more examples are given, as well
as a description for the format. Characters in single quotes in
the formats are case-insensitive (<literal>'t'</literal> could
be <literal>t</literal> or <literal>T</literal>), characters in
double quotes are case-sensitive (<literal>"T"</literal> is only
<literal>T</literal>).
</para>
<para>
To format <classname>DateTimeImmutable</classname> and
<classname>DateTime</classname> objects, please refer to the documentation
of the <function>DateTimeInterface::format</function> method.
</para>
<para>
A general set of rules should be taken into account.
</para>
<orderedlist>
<listitem>
<simpara>
The parser, allows for each unit (year, month, day, hour, minute, second)
the full range of values. For a year that's just 4 digits, for a month
that's 0-12, day is 0-31, hour is 0-24, and minute is 0-59.
</simpara>
</listitem>
<listitem>
<simpara>
60 is allowed for seconds, as sometimes date strings with that
leapsecond do show up. But PHP implements Unix time where "60" is not
a valid second number and hence it overflows.
</simpara>
</listitem>
<listitem>
<simpara>
<function>strtotime</function> returns &false; if any number is outside of
the ranges, and <function>DateTimeImmutable::__construct</function> throws
an exception.
</simpara>
</listitem>
<listitem>
<simpara>
If a string contains a date, all time elements are reset to 0.
</simpara>
</listitem>
<listitem>
<simpara>
All less-significant time elements are reset to 0 if any part of a time is
present in the given string.
</simpara>
</listitem>
<listitem>
<simpara>
The parser is dumb, and doesn't do any checks to make it faster (and
more generic).
</simpara>
</listitem>
<listitem>
<simpara>
Besides rules for individual time elements, the parser also understand
more specific <link linkend="datetime.formats.compound">compound
formats</link>, such as parsing Unix timestamps
(<literal>@1690388256</literal>) and ISO Weekdates
(<literal>2008-W28-3</literal>).
</simpara>
</listitem>
<listitem>
<para>
There is an additional check if an invalid date is provided:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$res = date_parse("2015-09-31");
var_dump($res["warnings"]);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(1) {
[11] =>
string(27) "The parsed date was invalid"
}
]]>
</screen>
</informalexample>
</para>
</listitem>
<listitem>
<para>
It is already possible to handle the edge cases, but then
<function>DateTimeImmutable::createFromFormat</function> must be used
while supplying the correct format.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$res = DateTimeImmutable::createFromFormat("Y-m-d", "2015-09-34");
var_dump($res);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
object(DateTimeImmutable)#1 (3) {
["date"]=>
string(26) "2015-10-04 17:24:43.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/London"
}
]]>
</screen>
</informalexample>
</para>
</listitem>
</orderedlist>
<!--Time Formats: {{{-->
<sect1 annotations="chunk:false" xml:id="datetime.formats.time">
<title>Time Formats</title>
<para>
This page describes the different date/time formats in a BNF-like syntax,
that the <classname>DateTimeImmutable</classname>,
<classname>DateTime</classname>, <function>date_create</function>,
<function>date_create_immutable</function>, and
<function>strtotime</function> parser understands.
</para>
<para>
To format <classname>DateTimeImmutable</classname> and
<classname>DateTime</classname> objects, please refer to the documentation
of the <function>DateTimeInterface::format</function> method.
</para>
<table>
<title>Used Symbols</title>
<tgroup cols="3">
<thead>
<row>
<entry>Description</entry>
<entry>Formats</entry>
<entry>Examples</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>frac</literal></entry>
<entry>. [0-9]+</entry>
<entry>".21342", ".85"</entry>
</row>
<row>
<entry><literal>hh</literal></entry>
<entry>"0"?[1-9] | "1"[0-2]</entry>
<entry>"04", "7", "12"</entry>
</row>
<row>
<entry><literal>HH</literal></entry>
<entry>[01][0-9] | "2"[0-4]</entry>
<entry>"04", "07", "19"</entry>
</row>
<row>
<entry><literal>meridian</literal></entry>
<entry>[AaPp] .? [Mm] .? [\0\t ]</entry>
<entry>"A.m.", "pM", "am."</entry>
</row>
<row>
<entry><literal>MM</literal></entry>
<entry>[0-5][0-9]</entry>
<entry>"00", "12", "59"</entry>
</row>
<row>
<entry><literal>II</literal></entry>
<entry>[0-5][0-9]</entry>
<entry>"00", "12", "59"</entry>
</row>
<row>
<entry><literal>space</literal></entry>
<entry>[ \t]</entry>
<entry></entry>
</row>
<row>
<entry><literal>tz</literal></entry>
<entry>"("? [A-Za-z]{1,6} ")"? | [A-Z][a-z]+([_/][A-Z][a-z]+)+</entry>
<entry>"CEST", "Europe/Amsterdam", "America/Indiana/Knox"</entry>
</row>
<row>
<entry><literal>tzcorrection</literal></entry>
<entry>"GMT"? [+-] <literal>hh</literal> ":"? <literal>MM</literal>?</entry>
<entry>"+0400", "GMT-07:00", "-07:00"</entry>
</row>
</tbody>
</tgroup>
</table>
<table>
<title>12 Hour Notation</title>
<tgroup cols="3">
<thead>
<row>
<entry>Description</entry>
<entry>Format</entry>
<entry>Examples</entry>
</row>
</thead>
<tbody>
<row>
<entry>Hour only, with meridian</entry>
<entry><literal>hh</literal> <literal>space</literal>? <literal>meridian</literal></entry>
<entry>"4 am", "5PM"</entry>
</row>
<row>
<entry>Hour and minutes, with meridian</entry>
<entry><literal>hh</literal> [.:] <literal>MM</literal> <literal>space</literal>? <literal>meridian</literal></entry>
<entry>"4:08 am", "7:19P.M."</entry>
</row>
<row>
<entry>Hour, minutes and seconds, with meridian</entry>
<entry><literal>hh</literal> [.:] <literal>MM</literal> [.:] <literal>II</literal> <literal>space</literal>? <literal>meridian</literal></entry>
<entry>"4:08:37 am", "7:19:19P.M."</entry>
</row>
<row>
<entry>MS SQL (Hour, minutes, seconds and fraction with meridian)</entry>
<entry><literal>hh</literal> ":" <literal>MM</literal> ":" <literal>II</literal> [.:] [0-9]+ <literal>meridian</literal></entry>
<entry>"4:08:39:12313am"</entry>
</row>
</tbody>
</tgroup>
</table>
<table>
<title>24 Hour Notation</title>
<tgroup cols="3">
<thead>
<row>
<entry>Description</entry>
<entry>Format</entry>
<entry>Examples</entry>
</row>
</thead>
<tbody>
<row>
<entry>Hour and minutes</entry>
<entry>'t'? <literal>HH</literal> [.:] <literal>MM</literal></entry>
<entry>"04:08", "19.19", "T23:43"</entry>
</row>
<row>
<entry>Hour and minutes, no colon</entry>
<entry>'t'? <literal>HH</literal> <literal>MM</literal></entry>
<entry>"0408", "t1919", "T2343"</entry>
</row>
<row>
<entry>Hour, minutes and seconds</entry>
<entry>'t'? <literal>HH</literal> [.:] <literal>MM</literal> [.:] <literal>II</literal></entry>
<entry>"04.08.37", "t19:19:19"</entry>
</row>
<row>
<entry>Hour, minutes and seconds, no colon</entry>
<entry>'t'? <literal>HH</literal> <literal>MM</literal> <literal>II</literal></entry>
<entry>"040837", "T191919"</entry>
</row>
<row>
<entry>Hour, minutes, seconds and timezone</entry>
<entry>'t'? <literal>HH</literal> [.:] <literal>MM</literal> [.:] <literal>II</literal> <literal>space</literal>? ( <literal>tzcorrection</literal> | <literal>tz</literal> )</entry>
<entry>"040837CEST", "T191919-0700"</entry>
</row>
<row>
<entry>Hour, minutes, seconds and fraction</entry>
<entry>'t'? <literal>HH</literal> [.:] <literal>MM</literal> [.:] <literal>II</literal> <literal>frac</literal></entry>
<entry>"04.08.37.81412", "19:19:19.532453"</entry>
</row>
<row>
<entry>Time zone information</entry>
<entry><literal>tz</literal> | <literal>tzcorrection</literal></entry>
<entry>"CEST", "Europe/Amsterdam", "+0430", "GMT-06:00"</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<!--}}}-->
<!--Date Formats: {{{-->
<sect1 annotations="chunk:false" xml:id="datetime.formats.date">
<title>Date Formats</title>
<para>
This page describes the different date formats in a BNF-like syntax, that
the <classname>DateTimeImmutable</classname>,
<classname>DateTime</classname>, <function>date_create</function>,
<function>date_create_immutable</function>, and
<function>strtotime</function> parser understands.
</para>
<para>
To format <classname>DateTimeImmutable</classname> and
<classname>DateTime</classname> objects, please refer to the documentation
of the <function>DateTimeInterface::format</function> method.
</para>
<table>
<title>Used Symbols</title>
<tgroup cols="3">
<thead>
<row>
<entry>Description</entry>
<entry>Format</entry>
<entry>Examples</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>daysuf</literal></entry>
<entry>"st" | "nd" | "rd" | "th"</entry>
<entry></entry>
</row>
<row>
<entry><literal>dd</literal></entry>
<entry>([0-2]?[0-9] | "3"[01]) <literal>daysuf</literal>?</entry>
<entry>"7th", "22nd", "31"</entry>
</row>
<row>
<entry><literal>DD</literal></entry>
<entry>"0" [0-9] | [1-2][0-9] | "3" [01]</entry>
<entry>"07", "31"</entry>
</row>
<row>
<entry><literal>m</literal></entry>
<entry>'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"</entry>
<entry></entry>
</row>
<row>
<entry><literal>M</literal></entry>
<entry>'jan' | 'feb' | 'mar' | 'apr' | 'may' | 'jun' | 'jul' | 'aug' |
'sep' | 'sept' | 'oct' | 'nov' | 'dec'</entry>
<entry></entry>
</row>
<row>
<entry><literal>mm</literal></entry>
<entry>"0"? [0-9] | "1"[0-2]</entry>
<entry>"0", "04", "7", "12"</entry>
</row>
<row>
<entry><literal>MM</literal></entry>
<entry>"0" [0-9] | "1"[0-2]</entry>
<entry>"00", "04", "07", "12"</entry>
</row>
<row>
<entry><literal>y</literal></entry>
<entry>[0-9]{1,4}</entry>
<entry>"00", "78", "08", "8", "2008"</entry>
</row>
<row>
<entry><literal>yy</literal></entry>
<entry>[0-9]{2}</entry>
<entry>"00", "08", "78"</entry>
</row>
<row>
<entry><literal>YY</literal></entry>
<entry>[0-9]{4}</entry>
<entry>"2000", "2008", "1978"</entry>
</row>
<row>
<entry><literal>YYY</literal></entry>
<entry>[0-9]{5,19}</entry>
<entry>"81412", "20192"</entry>
</row>
</tbody>
</tgroup>
</table>
<table>
<title>Localized Notations</title>
<tgroup cols="3">
<thead>
<row>
<entry>Description</entry>
<entry>Format</entry>
<entry>Examples</entry>
</row>
</thead>
<tbody>
<row>
<entry>American month and day</entry>
<entry><literal>mm</literal> "/" <literal>dd</literal></entry>
<entry>"5/12", "10/27"</entry>
</row>
<row>
<entry>American month, day and year</entry>
<entry><literal>mm</literal> "/" <literal>dd</literal> "/" <literal>y</literal></entry>
<entry>"12/22/78", "1/17/2006", "1/17/6"</entry>
</row>
<row>
<entry>Four digit year, month and day with slashes</entry>
<entry><literal>YY</literal> "/" <literal>mm</literal> "/" <literal>dd</literal></entry>
<entry>"2008/6/30", "1978/12/22"</entry>
</row>
<row>
<entry>Four digit year and month (GNU)</entry>
<entry><literal>YY</literal> "-" <literal>mm</literal></entry>
<entry>"2008-6", "2008-06", "1978-12"</entry>
</row>
<row>
<entry>Year, month and day with dashes</entry>
<entry><literal>y</literal> "-" <literal>mm</literal> "-" <literal>dd</literal></entry>
<entry>"2008-6-30", "78-12-22", "8-6-21"</entry>
</row>
<row>
<entry>Day, month and four digit year, with dots, tabs or dashes</entry>
<entry><literal>dd</literal> [.\t-] <literal>mm</literal> [.-] <literal>YY</literal></entry>
<entry>"30-6-2008", "22.12.1978"</entry>
</row>
<row>
<entry>Day, month and two digit year, with dots or tabs</entry>
<entry><literal>dd</literal> [.\t] <literal>mm</literal> "." <literal>yy</literal></entry>
<entry>"30.6.08", "22\t12.78"</entry>
</row>
<row>
<entry>Day, textual month and year</entry>
<entry><literal>dd</literal> ([ \t.-])* <literal>m</literal> ([ \t.-])* <literal>y</literal></entry>
<entry>"30-June 2008", "22DEC78", "14 III 1879"</entry>
</row>
<row>
<entry>Textual month and four digit year (Day reset to 1)</entry>
<entry><literal>m</literal> ([ \t.-])* <literal>YY</literal></entry>
<entry>"June 2008", "DEC1978", "March 1879"</entry>
</row>
<row>
<entry>Four digit year and textual month (Day reset to 1)</entry>
<entry><literal>YY</literal> ([ \t.-])* <literal>m</literal></entry>
<entry>"2008 June", "1978-XII", "1879.MArCH"</entry>
</row>
<row>
<entry>Textual month, day and year</entry>
<entry><literal>m</literal> ([ .\t-])* <literal>dd</literal> [,.stndrh\t ]+ <literal>y</literal></entry>
<entry>"July 1st, 2008", "April 17, 1790", "May.9,78"</entry>
</row>
<row>
<entry>Textual month and day</entry>
<entry><literal>m</literal> ([ .\t-])* <literal>dd</literal> [,.stndrh\t ]*</entry>
<entry>"July 1st,", "Apr 17", "May.9"</entry>
</row>
<row>
<entry>Day and textual month</entry>
<entry><literal>dd</literal> ([ .\t-])* <literal>m</literal></entry>
<entry>"1 July", "17 Apr", "9.May"</entry>
</row>
<row>
<entry>Month abbreviation, day and year</entry>
<entry><literal>M</literal> "-" <literal>DD</literal> "-" <literal>y</literal></entry>
<entry>"May-09-78", "Apr-17-1790"</entry>
</row>
<row>
<entry>Year, month abbreviation and day</entry>
<entry><literal>y</literal> "-" <literal>M</literal> "-" <literal>DD</literal></entry>
<entry>"78-Dec-22", "1814-MAY-17"</entry>
</row>
<row>
<entry>Year (and just the year)</entry>
<entry><literal>YY</literal></entry>
<entry>"1978", "2008"</entry>
</row>
<row>
<entry>Year (expanded, 5-19 digits with sign)</entry>
<entry>[+-] <literal>YYY</literal></entry>
<entry>"-81120", "+20192"</entry>
</row>
<row>
<entry>Textual month (and just the month)</entry>
<entry><literal>m</literal></entry>
<entry>"March", "jun", "DEC"</entry>
</row>
</tbody>
</tgroup>
</table>
<table>
<title>ISO8601 Notations</title>
<tgroup cols="3">
<thead>
<row>
<entry>Description</entry>
<entry>Format</entry>
<entry>Examples</entry>
</row>
</thead>
<tbody>
<row>
<entry>Eight digit year, month and day</entry>
<entry><literal>YY</literal> <literal>MM</literal> <literal>DD</literal></entry>
<entry>"15810726", "19780417", "18140517"</entry>
</row>
<row>
<entry>Four digit year, month and day with slashes</entry>
<entry><literal>YY</literal> "/" <literal>MM</literal> "/" <literal>DD</literal></entry>
<entry>"2008/06/30", "1978/12/22"</entry>
</row>
<row>
<entry>Two digit year, month and day with dashes</entry>
<entry><literal>yy</literal> "-" <literal>MM</literal> "-" <literal>DD</literal></entry>
<entry>"08-06-30", "78-12-22"</entry>
</row>
<row>
<entry>Four digit year with optional sign, month and day</entry>
<entry>[+-]? <literal>YY</literal> "-" <literal>MM</literal> "-" <literal>DD</literal></entry>
<entry>"-0002-07-26", "+1978-04-17", "1814-05-17"</entry>
</row>
<row>
<entry>Five+ digit year with required sign, month and day</entry>
<entry>[+-] <literal>YYY</literal> "-" <literal>MM</literal> "-" <literal>DD</literal></entry>
<entry>"-81120-02-26", "+20192-04-17"</entry>
</row>
</tbody>
</tgroup>
</table>
<note>
<para>
For the <literal>y</literal> and <literal>yy</literal>
formats, years below 100 are handled in a special way when the
<literal>y</literal> or <literal>yy</literal> symbol is used.
If the year falls in the range 0 (inclusive) to 69 (inclusive),
2000 is added. If the year falls in the range 70 (inclusive) to
99 (inclusive) then 1900 is added. This means that "00-01-01" is
interpreted as "2000-01-01".
</para>
</note>
<note>
<para>
The "Day, month and two digit year, with dots or tabs" format
(<literal>dd</literal> [.\t] <literal>mm</literal> "."
<literal>yy</literal>) only works for the year values 61 (inclusive)
to 99 (inclusive) - outside those years the <emphasis>time
format</emphasis> "<literal>HH</literal> [.:] <literal>MM</literal>
[.:] <literal>SS</literal>" has precedence.
</para>
</note>
<note>
<para>
The "Year (and just the year)" format only reliably works if a time string
has already been found. Otherwise, if the four digit year matches
<literal>HH</literal> <literal>MM</literal> then these two date elements
are set instead.
</para>
<para>
To consistently parse just a year, use
<function>DateTimeImmutable::createFromFormat</function> with the
<literal>Y</literal> specifier.
</para>
</note>
<caution>
<para>
It is possible to over- and underflow the <literal>dd</literal> and
<literal>DD</literal> format. Day 0 means the last day of previous
month, whereas overflows count into the next month. This makes
"2008-08-00" equivalent to "2008-07-31" and "2008-06-31" equivalent
to "2008-07-01" (June only has 30 days).
</para>
<para>
Note that the day range is restricted to 0-31 as indicated
by the regular expression above. Thus "2008-06-32" is not a valid date
string, for instance.
</para>
<para>
It is also possible to underflow the <literal>mm</literal> and
<literal>MM</literal> formats with the value 0. A month value of
0 means December of the previous year. As example "2008-00-22" is
equivalent to "2007-12-22".
</para>
<para>
If you combine the previous two facts and underflow both the day and
the month, the following happens: "2008-00-00" first gets converted
to "2007-12-00" which then gets converted to "2007-11-30". This also
happens with the string "0000-00-00", which gets transformed into
"-0001-11-30" (the year -1 in the ISO 8601 calendar, which is 2 BC
in the proleptic Gregorian calendar).
</para>
</caution>
</sect1>
<!--}}}-->
<!--Compound Formats: {{{-->
<sect1 annotations="chunk:false" xml:id="datetime.formats.compound">
<title>Compound Formats</title>
<para>
This page describes the different compound date/time formats in a BNF-like
syntax, that the <classname>DateTimeImmutable</classname>,
<classname>DateTime</classname>, <function>date_create</function>,
<function>date_create_immutable</function>, and
<function>strtotime</function> parser understands.
</para>
<para>
To format <classname>DateTimeImmutable</classname> and
<classname>DateTime</classname> objects, please refer to the documentation
of the <function>DateTimeInterface::format</function> method.
</para>
<table>
<title>Used Symbols</title>
<tgroup cols="3">
<thead>
<row>
<entry>Description</entry>
<entry>Formats</entry>
<entry>Examples</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>DD</literal></entry>
<entry>"0" [0-9] | [1-2][0-9] | "3" [01]</entry>
<entry>"02", "12", "31"</entry>
</row>
<row>
<entry><literal>doy</literal></entry>
<entry>"00"[1-9] | "0"[1-9][0-9] | [1-2][0-9][0-9] | "3"[0-5][0-9] | "36"[0-6]</entry>
<entry>"001", "012", "180", "350", "366"</entry>
</row>
<row>
<entry><literal>frac</literal></entry>
<entry>. [0-9]+</entry>
<entry>".21342", ".85"</entry>
</row>
<row>
<entry><literal>hh</literal></entry>
<entry>"0"?[1-9] | "1"[0-2]</entry>
<entry>"04", "7", "12"</entry>
</row>
<row>
<entry><literal>HH</literal></entry>
<entry>[01][0-9] | "2"[0-4]</entry>
<entry>"04", "07", "19"</entry>
</row>
<row>
<entry><literal>meridian</literal></entry>
<entry>[AaPp] .? [Mm] .? [\0\t ]</entry>
<entry>"A.m.", "pM", "am."</entry>
</row>
<row>
<entry><literal>ii</literal></entry>
<entry>[0-5]?[0-9]</entry>
<entry>"04", "8", "59"</entry>
</row>
<row>
<entry><literal>II</literal></entry>
<entry>[0-5][0-9]</entry>
<entry>"04", "08", "59"</entry>
</row>
<row>
<entry><literal>M</literal></entry>
<entry>'jan' | 'feb' | 'mar' | 'apr' | 'may' | 'jun' | 'jul' | 'aug' | 'sep' | 'sept' | 'oct' | 'nov' | 'dec'</entry>
<entry></entry>
</row>
<row>
<entry><literal>MM</literal></entry>
<entry>[0-1][0-9]</entry>
<entry>"00", "12"</entry>
</row>
<row>
<entry><literal>space</literal></entry>
<entry>[ \t]</entry>
<entry></entry>
</row>
<row>
<entry><literal>ss</literal></entry>
<entry>([0-5]?[0-9])|60</entry>
<entry>"04", "8", "59", "60" (leap second)</entry>
</row>
<row>
<entry><literal>SS</literal></entry>
<entry>[0-5][0-9]</entry>
<entry>"04", "08", "59"</entry>
</row>
<row>
<entry><literal>W</literal></entry>
<entry>"0"[1-9] | [1-4][0-9] | "5"[0-3]</entry>
<entry>"05", "17", "53"</entry>
</row>
<row>
<entry><literal>tzcorrection</literal></entry>
<entry>"GMT"? [+-] <literal>hh</literal> ":"? <literal>II</literal>?</entry>
<entry>"+0400", "GMT-07:00", "-07:00"</entry>
</row>
<row>
<entry><literal>YY</literal></entry>
<entry>[0-9]{4}</entry>
<entry>"2000", "2008", "1978"</entry>
</row>
</tbody>
</tgroup>
</table>
<table>
<title>Standards Formats</title>
<tgroup cols="2">
<thead>
<row>
<entry>Description</entry>
<entry>Examples</entry>
</row>
</thead>
<tbody>
<row>
<entry>ATOM</entry>
<entry>"2022-06-02T16:58:35+00:00"</entry>
</row>
<row>
<entry>COOKIE</entry>
<entry>"Thursday, 02-Jun-2022 16:58:35 UTC"</entry>
</row>
<row>
<entry>ISO8601</entry>
<entry>"2022-06-02T16:58:35+0000"</entry>
</row>
<row>
<entry><link xlink:href="&url.rfc;822">RFC 822</link></entry>
<entry>"Thu, 02 Jun 22 16:58:35 +0000"</entry>
</row>
<row>
<entry><link xlink:href="&url.rfc;850">RFC 850</link></entry>
<entry>"Thursday, 02-Jun-22 16:58:35 UTC"</entry>
</row>
<row>
<entry><link xlink:href="&url.rfc;1036">RFC 1036</link></entry>
<entry>"Thu, 02 Jun 22 16:58:35 +0000"</entry>
</row>
<row>
<entry><link xlink:href="&url.rfc;1123">RFC 1123</link></entry>
<entry>"Thu, 02 Jun 2022 16:58:35 +0000"</entry>
</row>
<row>
<entry><link xlink:href="&url.rfc;2822">RFC 2822</link></entry>
<entry>"Thu, 02 Jun 2022 16:58:35 +0000"</entry>
</row>
<row>
<entry><link xlink:href="&url.rfc;3339">RFC 3339</link></entry>
<entry>"2022-06-02T16:58:35+00:00"</entry>
</row>
<row>
<entry><link xlink:href="&url.rfc;3339">RFC 3339</link> Extended</entry>
<entry>"2022-06-02T16:58:35.698+00:00"</entry>
</row>
<row>
<entry><link xlink:href="&url.rfc;7231">RFC 7231</link></entry>
<entry>"Thu, 02 Jun 2022 16:58:35 GMT"</entry>
</row>
<row>
<entry>RSS</entry>
<entry>"Thu, 02 Jun 2022 16:58:35 +0000"</entry>
</row>
<row>
<entry>W3C</entry>
<entry>"2022-06-02T16:58:35+00:00"</entry>
</row>
</tbody>
</tgroup>
</table>
<table>
<title>Localized Notations</title>
<tgroup cols="3">
<thead>
<row>
<entry>Description</entry>
<entry>Format</entry>
<entry>Examples</entry>
</row>
</thead>
<tbody>
<row>
<entry>Common Log Format</entry>
<entry><literal>dd</literal> "/" <literal>M</literal> "/" <literal>YY</literal> : <literal>HH</literal> ":" <literal>II</literal> ":" <literal>SS</literal> <literal>space</literal> <literal>tzcorrection</literal></entry>
<entry>"10/Oct/2000:13:55:36 -0700"</entry>
</row>
<row>
<entry>EXIF</entry>
<entry><literal>YY</literal> ":" <literal>MM</literal> ":" <literal>DD</literal> " " <literal>HH</literal> ":" <literal>II</literal> ":" <literal>SS</literal></entry>
<entry>"2008:08:07 18:11:31"</entry>
</row>
<row>
<entry>ISO year with ISO week</entry>
<entry><literal>YY</literal> "-"? "W" <literal>W</literal></entry>
<entry>"2008W27", "2008-W28"</entry>
</row>
<row>
<entry>ISO year with ISO week and day</entry>
<entry><literal>YY</literal> "-"? "W" <literal>W</literal> "-"? [0-7]</entry>
<entry>"2008W273", "2008-W28-3"</entry>
</row>
<row>
<entry>MySQL</entry>
<entry><literal>YY</literal> "-" <literal>MM</literal> "-" <literal>DD</literal> " " <literal>HH</literal> ":" <literal>II</literal> ":" <literal>SS</literal></entry>
<entry>"2008-08-07 18:11:31"</entry>
</row>
<row>
<entry>PostgreSQL: Year with day-of-year</entry>
<entry><literal>YY</literal> "."? <literal>doy</literal></entry>
<entry>"2008.197", "2008197"</entry>
</row>
<row>
<entry>SOAP</entry>
<entry><literal>YY</literal> "-" <literal>MM</literal> "-" <literal>DD</literal> "T" <literal>HH</literal> ":" <literal>II</literal> ":" <literal>SS</literal> <literal>frac</literal> <literal>tzcorrection</literal>?</entry>
<entry>"2008-07-01T22:35:17.02", "2008-07-01T22:35:17.03+08:00"</entry>
</row>
<row>
<entry>Unix Timestamp</entry>
<entry>"@" "-"? [0-9]+</entry>
<entry>"@1215282385"</entry>
</row>
<row>
<entry>Unix Timestamp with microseconds</entry>
<entry>"@" "-"? [0-9]+ "." [0-9]{0,6}</entry>
<entry>"@1607974647.503686"</entry>
</row>
<row>
<entry>XMLRPC</entry>
<entry><literal>YY</literal> <literal>MM</literal> <literal>DD</literal> "T" <literal>hh</literal> ":" <literal>II</literal> ":" <literal>SS</literal></entry>
<entry>"20080701T22:38:07", "20080701T9:38:07"</entry>
</row>
<row>
<entry>XMLRPC (Compact)</entry>
<entry><literal>YY</literal> <literal>MM</literal> <literal>DD</literal> 't' <literal>hh</literal> <literal>II</literal> <literal>SS</literal></entry>
<entry>"20080701t223807", "20080701T093807"</entry>
</row>
<row>
<entry>WDDX</entry>
<entry><literal>YY</literal> "-" <literal>mm</literal> "-" <literal>dd</literal> "T" <literal>hh</literal> ":" <literal>ii</literal> ":" <literal>ss</literal></entry>
<entry>"2008-7-1T9:3:37"</entry>
</row>
</tbody>
</tgroup>
</table>
<note>
<para>
The "W" in the "ISO year with ISO week" and "ISO year with ISO week
and day" formats is case-sensitive, you can only use the upper case
"W".
</para>
<para>
The "T" in the SOAP, XMLRPC and WDDX formats is case-sensitive, you
can only use the upper case "T".
</para>
<para>
The "Unix Timestamp" format sets the timezone to UTC.
</para>
</note>
</sect1>
<!--}}}-->
<!--Relative Formats: {{{-->
<sect1 annotations="chunk:false" xml:id="datetime.formats.relative">
<title>Relative Formats</title>
<para>
This page describes the different relative date/time formats in a BNF-like
syntax, that the <classname>DateTimeImmutable</classname>,
<classname>DateTime</classname>, <function>date_create</function>,
<function>date_create_immutable</function>, and
<function>strtotime</function> parser understands.
</para>
<para>
To format <classname>DateTimeImmutable</classname> and
<classname>DateTime</classname> objects, please refer to the documentation
of the <function>DateTimeInterface::format</function> method.
</para>
<table>
<title>Used Symbols</title>
<tgroup cols="2">
<thead>
<row>
<entry>Description</entry>
<entry>Format</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>dayname</literal></entry>
<entry>'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' |
'friday' | 'saturday' | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' |
'sat'</entry>
</row>
<row>
<entry><literal>daytext</literal></entry>
<entry>'weekday' | 'weekdays'</entry>
</row>
<row>
<entry><literal>number</literal></entry>
<entry>[+-]?[0-9]+</entry>
</row>
<row>
<entry><literal>ordinal</literal></entry>
<entry>'first' | 'second' | 'third' | 'fourth' | 'fifth' | 'sixth' |
'seventh' | 'eighth' | 'ninth' | 'tenth' | 'eleventh' | 'twelfth' |
'next' | 'last' | 'previous' | 'this'</entry>
</row>
<row>
<entry><literal>reltext</literal></entry>
<entry>'next' | 'last' | 'previous' | 'this'</entry>
</row>
<row>
<entry><literal>space</literal></entry>
<entry>[ \t]+</entry>
</row>
<row>
<entry><literal>unit</literal></entry>
<entry>'ms' | 'µs' | (( 'msec' | 'millisecond' | 'µsec' | 'microsecond'
| 'usec' | 'sec' | 'second' | 'min' | 'minute' | 'hour' | 'day' |
'fortnight' | 'forthnight' | 'month' | 'year') 's'?) | 'weeks' |
<literal>daytext</literal></entry>
</row>
</tbody>
</tgroup>
</table>
<table>
<title>Day-based Notations</title>
<tgroup cols="3">
<thead>
<row>
<entry>Format</entry>
<entry>Description</entry>
<entry>Examples</entry>
</row>
</thead>
<tbody>
<row>
<entry>'yesterday'</entry>
<entry>Midnight of yesterday</entry>
<entry>"yesterday 14:00"</entry>
</row>
<row>
<entry>'midnight'</entry>
<entry>The time is set to 00:00:00</entry>
<entry></entry>
</row>
<row>
<entry>'today'</entry>
<entry>The time is set to 00:00:00</entry>
<entry></entry>
</row>
<row>
<entry>'now'</entry>
<entry>Now - this is simply ignored</entry>
<entry></entry>
</row>
<row>
<entry>'noon'</entry>
<entry>The time is set to 12:00:00</entry>
<entry>"yesterday noon"</entry>
</row>
<row>
<entry>'tomorrow'</entry>
<entry>Midnight of tomorrow</entry>
<entry></entry>
</row>
<row>
<entry>'back of' <literal>hour</literal></entry>
<entry>15 minutes past the specified hour</entry>
<entry>"back of 7pm", "back of 15"</entry>
</row>
<row>
<entry>'front of' <literal>hour</literal></entry>
<entry>15 minutes before the specified hour</entry>
<entry>"front of 5am", "front of 23"</entry>
</row>
<row>
<entry>'first day of'</entry>
<entry>Sets the day of the first of the current month. This phrase is
usually best used together with a month name following it as it only
effects the current month</entry>
<entry>"first day of January 2008"</entry>
</row>
<row>
<entry>'last day of'</entry>
<entry>Sets the day to the last day of the current month. This phrase is
usually best used together with a month name following it as it only
effects the current month</entry>
<entry>"last day of next month"</entry>
</row>
<row>
<entry><literal>ordinal</literal> <literal>space</literal> <literal>dayname</literal> <literal>space</literal> 'of'</entry>
<entry>Calculates the <literal>x</literal>-th week day of the current month.</entry>
<entry>"first sat of July 2008"</entry>
</row>
<row>
<entry>'last' <literal>space</literal> <literal>dayname</literal> <literal>space</literal> 'of'</entry>
<entry>Calculates the <emphasis>last</emphasis> week day of the current month.</entry>
<entry>"last sat of July 2008"</entry>
</row>
<row>
<entry><literal>number</literal> <literal>space</literal>? (<literal>unit</literal> | 'week')</entry>
<entry>Handles relative time items where the value is a number.</entry>
<entry>"+5 weeks", "12 day", "-7 weekdays"</entry>
</row>
<row>
<entry>(<literal>ordinal</literal> | <literal>reltext</literal>) <literal>space</literal> <literal>unit</literal></entry>
<entry>Handles relative time items where the value is text.
<literal>last</literal> and <literal>previous</literal> are equivalent
to <literal>-1</literal>, <literal>this</literal> to nothing, and
<literal>next</literal> to <literal>+1</literal>.</entry>
<entry>"fifth day", "second month", "last day", "previous year"</entry>
</row>
<row>
<entry>'ago'</entry>
<entry>Negates all the values of previously found relative time items.</entry>
<entry>"2 days ago", "8 days ago 14:00", "2 months 5 days ago", "2 months ago 5 days", "2 days ago"</entry>
</row>
<row>
<entry><literal>dayname</literal></entry>
<entry>
Moves to the next day of this name. (See <link
linkend="datetime.formats.relative.dayname-note">note</link>)
</entry>
<entry>"Monday"</entry>
</row>
<row>
<entry><literal>reltext</literal> <literal>space</literal> 'week'</entry>
<entry>Handles the special format "weekday + last/this/next week".</entry>
<entry>"Monday next week"</entry>
</row>
</tbody>
</tgroup>
</table>
<note>
<para>
Relative statements are always processed <emphasis>after</emphasis>
non-relative statements. This makes "+1 week july 2008" and "july
2008 +1 week" equivalent.
</para>
<para>
Exceptions to this rule are: "yesterday", "midnight", "today", "noon"
and "tomorrow". Note that "tomorrow 11:00" and "11:00 tomorrow"
are different. Considering today's date of "July 23rd, 2008" the
first one produces "2008-07-24 11:00" where as the second one
produces "2008-07-24 00:00". The reason for this is that those
five statements directly influence the current time.
</para>
<para>
Keywords such as "first day of" depend on the context in which the
relative format string is used. If used with a static method or function,
the referent is the current system timestamp. However, if used in
<function>DateTime::modify</function> or
<function>DateTimeImmutable::modify</function>, the referent is the object
on which the <literal>modify()</literal> method is called.
</para>
</note>
<note>
<para xml:id="datetime.formats.relative.dayname-note">
Observe the following remarks when the current day-of-week is the
same as the day-of-week used in the date/time string. The current
day-of-week could have been (re-)calculated by non-relative parts of
the date/time string however.
</para>
<orderedlist>
<listitem>
<simpara>
"<literal>dayname</literal>" does <emphasis>not</emphasis> advance to
another day. (Example: "Wed July 23rd, 2008" means "2008-07-23").
</simpara>
</listitem>
<listitem>
<simpara>
"<literal>number</literal> <literal>dayname</literal>" does
<emphasis>not</emphasis> advance to another day. (Example: "1
wednesday july 23rd, 2008" means "2008-07-23").
</simpara>
</listitem>
<listitem>
<simpara>
"<literal>number</literal> week <literal>dayname</literal>" will
first add the number of weeks, but does <emphasis>not</emphasis>
advance to another day. In this case "<literal>number</literal>
week" and "<literal>dayname</literal>" are two distinct blocks.
(Example: "+1 week wednesday july 23rd, 2008" means "2008-07-30").
</simpara>
</listitem>
<listitem>
<simpara>
"<literal>ordinal</literal> <literal>dayname</literal>"
<emphasis>does</emphasis> advance to another day. (Example "first
wednesday july 23rd, 2008" means "2008-07-30").
</simpara>
</listitem>
<listitem>
<simpara>
"<literal>number</literal> week <literal>ordinal</literal>
<literal>dayname</literal>" will first add the number of
weeks, and then <emphasis>advances</emphasis> to another
day. In this case "<literal>number</literal> week" and
"<literal>ordinal</literal> <literal>dayname</literal>" are two
distinct blocks. (Example: "+1 week first wednesday july 23rd,
2008" means "2008-08-06").
</simpara>
</listitem>
<listitem>
<simpara>
"<literal>ordinal</literal> <literal>dayname</literal> 'of' "
does <emphasis>not</emphasis> advance to another day. (Example:
"first wednesday of july 23rd, 2008" means "2008-07-02" because
the specific phrase with 'of' resets the day-of-month to '1' and
the '23rd' is ignored here).
</simpara>
</listitem>
</orderedlist>
<para>
Also observe that the "of" in "<literal>ordinal</literal>
<literal>space</literal> <literal>dayname</literal>
<literal>space</literal> 'of' " and "'last' <literal>space</literal>
<literal>dayname</literal> <literal>space</literal> 'of' " does
something special.
</para>
<orderedlist>
<listitem>
<simpara>
It sets the day-of-month to 1.
</simpara>
</listitem>
<listitem>
<simpara>
"<literal>ordinal</literal> <literal>dayname</literal> 'of' " does
<emphasis>not</emphasis> advance to another day. (Example: "first
tuesday of july 2008" means "2008-07-01").
</simpara>
</listitem>
<listitem>
<simpara>
"<literal>ordinal</literal> <literal>dayname</literal> "
<emphasis>does</emphasis> advance to another day. (Example: "first
tuesday july 2008" means "2008-07-08", see also point 4 in the
list above).
</simpara>
</listitem>
<listitem>
<simpara>
"'last' <literal>dayname</literal> 'of' " takes the last
<literal>dayname</literal> of the current month. (Example: "last
wed of july 2008" means "2008-07-30")
</simpara>
</listitem>
<listitem>
<simpara>
"'last' <literal>dayname</literal>" takes the last
<literal>dayname</literal> from the current day. (Example: "last
wed july 2008" means "2008-06-25"; "july 2008" first sets the
current date to "2008-07-01" and then "last wed" moves to the
previous Wednesday which is "2008-06-25").
</simpara>
</listitem>
</orderedlist>
</note>
<note>
<para>
Relative month values are calculated based on the length of months that
they pass through. An example would be "+2 month 2011-11-30", which would
produce "2012-01-30". This is due to November being 30 days in length, and
December being 31 days in length, producing a total of 61 days.
</para>
</note>
<note>
<para>
<literal>number</literal> is an <emphasis>integer</emphasis> number; if a
decimal number is given, the dot (or comma) is likely interpreted as delimiter.
For instance, <literal>'+1.5 hours'</literal> is parsed like
<literal>'+1 5 hours'</literal>, not as <literal>'+1 hour +30 minutes'</literal>.
</para>
</note>
<sect2 role="changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>8.4.0</entry>
<entry>
<literal>number</literal> now again accepts a plus sign followed by a
minus sign, e.g. <literal>+-2</literal>, and other combinations of
multiple signs.
</entry>
</row>
<row>
<entry>8.2.0</entry>
<entry>
<literal>number</literal> no longer accepts a plus sign followed by a
minus sign, e.g. <literal>+-2</literal>.
</entry>
</row>
<row>
<entry>7.0.8</entry>
<entry>
Weeks always start on monday. Formerly, sunday would also be considered
to start a week.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</sect2>
</sect1>
<!--}}}-->
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=marker fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->