Bug #76731 [Com]: Date time format parsing is wrong for format Ynd

From: Date: Mon, 13 Aug 2018 10:41:25 +0000
Subject: Bug #76731 [Com]: Date time format parsing is wrong for format Ynd
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-216760@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=76731&edit=1

 ID:                 76731
 Comment by:         remy dot fox at simbuka dot com
 Reported by:        remy dot fox at simbuka dot com
 Summary:            Date time format parsing is wrong for format Ynd
 Status:             Open
 Type:               Bug
 Package:            Date/time related
 PHP Version:        7.2.8
 Block user comment: N
 Private report:     N

 New Comment:

You are right that I made a mistake in the first example.

On the date webpage (http://php.net/manual/en/function.date.php) the 'd' specifier is
prescribed as 'Day of the month, 2 digits with leading zeros', which is why my conclusion
was that the parsing must be wrong. Of course if the documentation is inaccurate because the
'd' actually means *up to* 2 digits, then the bug report is not valid.

Though in my opinion *up to* 2 digits is rather confusing and I think that the current documentation
on the date function (although not representing the current state of the functionality) is more
consistent. I'd suggest fixing the functionality to match the date function's
documentation rather than the other way around.


Previous Comments:
------------------------------------------------------------------------
[2018-08-13 07:58:57] derick@php.net

Your first sample fails because you didn't specify the - in your format:

derick@singlemalt:~ $ php

<?php
$date = DateTime::createFromFormat("Y-m-d", "2000-10-1");
var_dump($date);

Standard input code:3:
class DateTime#1 (3) {
  public $date =>
  string(26) "2000-10-01 07:55:25.000000"
  public $timezone_type =>
  int(3)
  public $timezone =>
  string(3) "UTC"
}

Works just fine here.

The format characters in createFromFormat take *up* to the amount of characters acceptable for the
format. So indeed, the "Y" parses 4 characters ("2000"), the "m"
parses 2 characters ("10"), and the "d" up to 2 characters, but as there is only
one, it parses only "1".

------------------------------------------------------------------------
[2018-08-13 00:58:02] requinix@php.net

> Both the month and day specifier are padded in 'Ymd'
Optionally padded. 2000101 gets parsed as Y=2000 m=10 d=1 so the zero isn't being reused.

PHP takes whatever digits are available when deciding whether to use one or two digits. If there are
two digits available then they both will be used. That's why "200012" does not work
with Ymd: Y=2000, m=12 because there are two digits available, and since there's nothing left
for d to match it fails. Even though it could have matched with m=1 d=2.

------------------------------------------------------------------------
[2018-08-12 23:24:05] a at b dot c dot de

Incidentally, I just noticed that this behaviour is documented on the createFromFormat() page.

"d and j 	Day of the month, 2 digits with or without leading zeros"

------------------------------------------------------------------------
[2018-08-12 23:19:16] a at b dot c dot de

In short: createFromFormat("Ymd", "2000101") should be rejected because it
doesn't have enough digits, right? There should be four for the year, two for the month, and
two for the day.

The test case can be simplified:

$date = DateTime::createFromFormat("d", "1");
var_dump($date);

Of the other "leading zero" format specifiers, "m", "h" and
"H" also parse, but "i" and "s" both fail.

------------------------------------------------------------------------
[2018-08-12 18:06:44] remy dot fox at simbuka dot com

You are right that sometimes there is ambiguity. For example, if we take the string
'2000111' then for the format 'Ynj' it could mean either 11 january or 1
november. This is because both the month and day specifiers are unpadded.

In my example there is no ambiguity though. Both the month and day specifier are padded in
'Ymd' and so the parsing should fail (i.e. return false), because the zero in position 6
is used twice now.

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=76731


--
Edit this bug report at https://bugs.php.net/bug.php?id=76731&edit=1


Thread (9 messages)

« previous php.bugs (#216760) next »