Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP DateTime CreateFromFormat Issue

Tags:

date

php

datetime

function validateDate($date, $format = 'm-Y') {
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}


validateDate('09-2017', 'm-Y');

function was copied from this answer or php.net

I'm very puzzled to why this returns false while it returns true for the previous months. Any ideas?

like image 216
theflarenet Avatar asked Aug 31 '17 18:08

theflarenet


2 Answers

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
like image 116
ishegg Avatar answered Sep 21 '22 12:09

ishegg


If you are not supplying a day. current one is used; just like explained in previous answer. But this can be quickly solved with one format sign: !, which resets all fields (year, month, day, hour, minute, second, fraction and timezone information) to the Unix Epoch; see format table.

Fix:

function validateDate($date, $format = 'm-Y') {
    $d = DateTime::createFromFormat('!'.$format, $date);
    return $d && $d->format($format) == $date;
}

function was copied from this answer or php.net

like image 35
Glavić Avatar answered Sep 25 '22 12:09

Glavić