It's because you're not supplying a day, so it's using the current day by default. Current day is 31, but September only has 30 days, so it skips to October 1st.
Look at this example:
function validateDate($date, $format = 'm-Y') {
$d = DateTime::createFromFormat($format, $date);
echo $d->format("d-".$format); // added the day for debugging
return $d && $d->format($format) == $date;
}
var_dump(validateDate('08-2017', 'm-Y')); // 31-08-2017, true
var_dump(validateDate('09-2017', 'm-Y')); // 01-10-2017, there's no 31-09-2017, false
function was copied from this answer or php.net
This is a little rudimentary, but you can detect if there's no d
in the format and manually set it to 1 to avoid this:
<?php
function validateDate($date, $format = 'm-Y') {
if (strpos($format, "d") === false) {
$format = "d ".$format;
$date = "01 ".$date;
}
$d = DateTime::createFromFormat($format, $date);
return $d && $d->format($format) === $date;
}
var_dump(validateDate('08-2017', 'm-Y')); // 31-08-2017, true
var_dump(validateDate('09-2017', 'm-Y')); // 01-09-2017, true