A string 2019-05-13T10:00:00.000Z
represents a date and time in the format ISO 8601.
To turn this string into a date, you can pass it directly to the constructor DateTime
:
$str = "2019-05-13T10:00:00.000Z";
$datetime = new DateTime($str);
With that you get the DateTime
corresponding. To transform it to another format, just use format
, passing the desired format:
echo $datetime->format('Y-m-d\TH:i:s');
This prints:
2019-05-13T10:00:00
If you want to use createFromFormat
, just use the corresponding format. According to the documentation, for the fraction of a second u
, and for offset (in this case the Z
in the end, that indicates that the date/time is in UTC), is used O
(capital letter "O"):
$datetime = DateTime::createFromFormat('Y-m-d\TH:i:s.uO', $str);
echo $datetime->format('Y-m-d\TH:i:s');
The result is the same as the previous code:
2019-05-13T10:00:00
Formatting x Parsing
Also note another detail:
createFromFormat
turns a string into a date (Parsing). Therefore, the first parameter should be the format the string is in, but you were using the format to which you wanted to convert ('Y-m-d\TH:i:s'
).
format
does the opposite: transforms the date into a string (formatting). Therefore the parameter of this method should be the format to which the date will be converted (here yes should be 'Y-m-d\TH:i:s'
). But you were trying to use the format in which the original string is.
Other formats for offset
The Z
in the end indicates that the date/time is in UTC.
But there are other possible values for offsets, such as +01:00
or -03:00
. And according to ISO8601, the offset "1 hour after UTC" can be represented in 3 ways: +01:00
, +0100
(without the two points) or +01
.
Fortunately, the above code also works for these formats:
// todos retornam a mesma data
$d = DateTime::createFromFormat('Y-m-d\TH:i:s.uO', "2019-05-13T10:00:00.000+01:00");
$d = DateTime::createFromFormat('Y-m-d\TH:i:s.uO', "2019-05-13T10:00:00.000+0100");
$d = DateTime::createFromFormat('Y-m-d\TH:i:s.uO', "2019-05-13T10:00:00.000+01");
$d = new DateTime("2019-05-13T10:00:00.000+01:00");
$d = new DateTime("2019-05-13T10:00:00.000+0100");
$d = new DateTime("2019-05-13T10:00:00.000+01");
Obs: there are some predefined formats, as described in the documentation, but they didn’t work.
For example, there is even the constant DateTime::ISO8601
, but she doesn’t consider the split second.
By the way, the documentation says that DateTime::ISO8601
"is not compatible with ISO 8601, but continues to exist for backwards compatibility reasons", and recommends that DateTime::ATOM
(but this constant also does not take into account the second fractions).
The closest to the format in question is DateTime::DATE_RFC3339_EXTENDED
(from PHP 7.0.0), which considers the second fractions, but it also did not work (apparently, it only works to format, but not to Parsing).
See here the attempt to use these constants, and note that all fail (the only one that works is the solution proposed at the beginning of this answer, using the format 'Y-m-d\TH:i:s.uO'
).
To documentation still cites that can be used P
or T
to offset (instead of O
). To the Parsing, there seems to be no difference:
$str = "2019-05-13T10:00:00.000Z";
// todos criam a mesma data
$d = DateTime::createFromFormat('Y-m-d\TH:i:s.uO', $str);
$d = DateTime::createFromFormat('Y-m-d\TH:i:s.uP', $str);
$d = DateTime::createFromFormat('Y-m-d\TH:i:s.uT', $str);
The difference between these formats occurs when formatting the date:
// usando data em UTC
$d = new DateTime("2019-05-13T10:00:00.000Z");
echo $d->format('O, P, T') . "\n";
// usando offset -03:00
$d = new DateTime("2019-05-13T10:00:00.000-03:00");
echo $d->format('O, P, T') . "\n";
In this case, the exit is:
+0000, +00:00, Z
-0300, -03:00, GMT-0300
That is to say, O
format the offset to HHMM
(hours and minutes without the two points), P
format using the two dots, and T
format for what documentation calls "Timezone abreviation" - in this case, the result was Z
for UTC and GMT-0300
to offset -03:00, but some timezones use names like PST (Pacific Standard Time, used on the west coast of the USA).
Anyway, these formats behave differently only in formatting. But for the Parsing, all worked for the strings in question.
I don’t know if you know. It has a php library Carbon with it and easy with date and time formatting.
– Richard Carlos