11

I can't seem to get DateTime::createFromFormat() to work in PHP 7.0.26

My code

date_default_timezone_set('America/New_York');

$t = '2018-02-23T11:29:16.434Z';
echo '$t: ' . json_encode($t) . PHP_EOL;
$f = DateTime::RFC3339_EXTENDED;
echo '$f: ' . json_encode($f) . PHP_EOL;
echo 'createFromFormat: ' . json_encode(DateTime::createFromFormat($f, $t)) . PHP_EOL;
echo 'getLastErrors: ' . json_encode(DateTime::getLastErrors()) . PHP_EOL;

$t = '2018-02-23T11:29:16.434+00:00';
echo '$t: ' . json_encode($t) . PHP_EOL;
echo 'createFromFormat: ' . json_encode(DateTime::createFromFormat($f, $t)) . PHP_EOL;
echo 'getLastErrors: ' . json_encode(DateTime::getLastErrors()) . PHP_EOL;

Output:

$t: "2018-02-23T11:29:16.434Z"
$f: "Y-m-d\\TH:i:s.vP"
createFromFormat: false
getLastErrors: {"warning_count":0,"warnings":[],"error_count":2,"errors":{"20":"The format separator does not match","21":"The timezone could not be found in the database"}}
$t: "2018-02-23T11:29:16.434+00:00"
createFromFormat: false
getLastErrors: {"warning_count":0,"warnings":[],"error_count":2,"errors":{"20":"The format separator does not match","21":"The timezone could not be found in the database"}}

I note that "v" is not listed in the values for the format parameter for DateTime::createFromFormat() -- but supposedly I should be able to use the const DateTime::RFC3339_EXTENDED which includes a "v". It also says that this const was added in version 7.0

user9645
  • 6,286
  • 6
  • 29
  • 43
  • 2
    You took note of http://php.net/manual/en/datetime.createfromformat.php#121431 already? – CBroe Feb 23 '18 at 13:10
  • @CBroe - No, I didn't see that it was waaaaay down the page. Thanks - put it as an answer so I can accept it. – user9645 Feb 23 '18 at 13:12
  • Happy enough with Alex' answer, he even looked into the details a bit more, so you might as well accept that one ;-) – CBroe Feb 23 '18 at 15:22
  • Yes it is. The "v" portion is not even in the docs so it cannot be parsed back. It seems it should be "u". Go figure. – istepaniuk Oct 16 '18 at 10:52

2 Answers2

20

As CBroe noted, this is the right solution for you. You should use Y-m-d\TH:i:s.uP instead of DateTime::RFC3339_EXTENDED, which is Y-m-d\TH:i:s.vP:

$date = DateTime::createFromFormat("Y-m-d\TH:i:s.uP", "2018-02-23T11:29:16.434Z"); //works

I actually went to take a look why this is happening, and here's what I found.

There is a closed bug requesting support for RFC3339 with milliseconds. The bug author created a pull request to add this feature. But whilst he created a RFC3339_EXTENDED constant for the format function, he did not add the support for createFromFormat. If you take a look here, there is no support for v option (which is milliseconds). So yeah.

Kevin Kopf
  • 13,327
  • 14
  • 49
  • 66
4

Yes, apparently it only got fixed in PHP 7.3.0, see this https://3v4l.org/4nMi4

enter image description here

max4ever
  • 11,909
  • 13
  • 77
  • 115