Formatting Date and Time

When trying to DateTime::createFromFormat date using DateTime::createFromFormat PHP will not recognize the time zone.

Example:

 $t = new \DateTime(); echo $t->format('Ym-dTH:i:s'); 

displays

 2012-01-24MSK16:53:52 

Now when I try to parse this line from the same format

 var_dump(\DateTime::createFromFormat('Ym-dTH:i:s', '2012-01-24MSK16:53:52')); 

I get

 bool(false) 

When I do not put the timezone on the line, it works

 $t = new \DateTime(); echo $t->format('Ym-dH:i:s'); 

will give

 2012-01-2417:17:24 

and parsing what

 var_dump(\DateTime::createFromFormat('Ym-dH:i:s', "2012-01-2417:17:24")); 

will give

 object(DateTime)#3 (3) { ["date"]=> string(19) "2012-01-24 17:17:24" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/Moscow" } 

Checked for

  • PHP 5.3.6-13ubuntu3.3 with Suhosin-Patch (cli) (built: Dec 13, 2011 18:18:37) and
  • PHP 5.3.9 (cli) (built: Jan 18, 2012 20:02:33)

The problem arises if we care about the time zone. This is mistake? Or what am I doing wrong? Thank you in advance!

+4
source share
2 answers

It looks like an error (or at least an undocumented restriction) with PHP ... If we try 4 possible iterations of spaces:

 var_dump(\DateTime::createFromFormat('Ym-dTH:i:s', '2012-01-24MSK16:53:52')); var_dump(\DateTime::createFromFormat('Ymd TH:i:s', '2012-01-24 MSK 16:53:52')); var_dump(\DateTime::createFromFormat('Ymd TH:i:s', '2012-01-24 MSK16:53:52')); var_dump(\DateTime::createFromFormat('Ym-dT H:i:s', '2012-01-24MSK 16:53:52')); 

We get (tested PHP 5.3, 5.4rc6 and Trunk):

 bool(false) object(DateTime)#2 (3) { ["date"]=> string(19) "2012-01-24 16:53:52" ["timezone_type"]=> int(2) ["timezone"]=> string(3) "MSK" } bool(false) object(DateTime)#3 (3) { ["date"]=> string(19) "2012-01-24 16:53:52" ["timezone_type"]=> int(2) ["timezone"]=> string(3) "MSK" } 

Thus, it seems that the time zone identifier and / or hour is space-sensitive ... Next:

 var_dump(\DateTime::createFromFormat('Ymd H:i:s', '2012-01-24 16:53:52')); var_dump(\DateTime::createFromFormat('Ym-dH:i:s', '2012-01-2416:53:52')); 

Gets the correct results. A:

 var_dump(\DateTime::createFromFormat('TY-m-d', 'MSK2012-01-24')); var_dump(\DateTime::createFromFormat('T Ym-d', 'MSK 2012-01-24')); 

Productivity:

 bool(false) object(DateTime)#4 (3) { ["date"]=> string(19) "2012-01-24 01:49:26" ["timezone_type"]=> int(2) ["timezone"]=> string(3) "MSK" } 

So it seems that the time zone specifier is sensitive to the trailing space ...

Edit: it is white sensitive

If we look at parse_date.c timelib_parse_from_format() on line 25075 , we will see that all 4 time zone formats are analyzed the same! This means that there is no difference between format identifiers for parsing, therefore, for parsing, they are interchangeable.

This in itself seems to be a mistake (or lack of function) enough to continue. But let's see what happens in timelib_get_zone() , which is called when using the timezone identifier. Well, looking, we can see what we call timelib_lookup_zone() when it is not GMT or a time offset.

And there we found a mistake. On line 768 of timelib_lookup_zone we will see that it will consume the entire input line to one of \0 (null), ) or a space:

 while (**ptr != '\0' && **ptr != ')' && **ptr != ' ') { ++*ptr; } 

As for fixing it, it's a little trickier. To fix this problem, you will need to re-implement the format parsers for each time zone. For the T parser, this is easy, as it is always a 3-line string. But for others, this is a little more interesting, as there are variable letters, and as such sensitivity to a space can be a problem.

In short, I would suggest just adding a finite white space to your timezone identifiers and do with it ...

+13
source

You can check if your php.ini has date.timezone by default and if you do not use date_default_timezone_set as DateTime relies on it.

0
source

Source: https://habr.com/ru/post/1392689/


All Articles