Incorrect Date Conversation (ndY to Y-m-d H: i: s)


My code is returning the wrong date conversation

$date = '8312015';
$newDate = DateTime::createFromFormat('ndY', $date);
$convertedDate = $newDate->format('Y-m-d H:i:s');
echo $convertedDate;


0021-11-12 17:04:56


2015-08-31 00:00:00


  1. Why PHP can't convert ndY to Y-m-d H:i:s
  2. Why PHP append the current hours, instead of 00:00:00

Note: I tried with date(), date_create, date_format and I got same results (wrong date)

So close! m is actually :

Numeric representation of a month, with leading zeros 01 through 12


So, that means it expects it to be 2 characters, not one. If you do

$date = '08312015';
$newDate = DateTime::createFromFormat('ndY', $date);

It works how you want it to

When you do

$date = '8312015';
$newDate = DateTime::createFromFormat('ndY', $date);

You get month=83, day=12, year=015

83 months is 6 years+ 11 months so, 015+6=21 years +11 months=november 11th of year 21, ie (0021-11-12), which matches the output

Edit: so apparantly you meant n not m, the problem being that you have no delimiter between date parts, so, as has been said, it is ambiguous as to whether the month should be 8 or 83...

Edit Again My "answer" just explained the problem I guess without showing how to fix it, so...

If the fields are not delimited either by a delimiting character (like a -) or by field length (ie, how m is always 2 characters) then the conversion is ambiguous. Given that apparantly php considers 83 a valid month, and that a month formatted as n may have 1 or more digits, when php sees 83, it really can't know if you mean "8th month and then something starting with a 3" or "the 83rd month".

So, what you need to do is disambiguate the delimiting. One way to disambiguate is to pad with 0s on the left, since d (and for all intents and purposes Y) are always the same amount of digits (2 and 4, respectively)

So, $date=str_pad($date, 8, "0", STR_PAD_LEFT); would turn 8312015 into 08312015, and then you could use m to format instead of n, and you should be OK from there. For months > 9, it would not change the input string, so it would be safe for all strings in that ndY format.