0

I'm having problems comparing two dates in PHP. I want to compare the current date to one entered by a user.

$date = "18/05/2018";

The date input by the user.

$date_unix = strtotime($date);

Used to convert the date from the given format to time, in order to be compared.

if($date_unix < time()){
        echo '<b>Notice:</b> You cannot specify a date in the past.<br>';
    }

The above if statement is always run and i'm confused as to why. Any help would be appreciated.

Orbie
  • 7
  • 5
  • 1
    `$date = ["18/05/2018"];` this is an array! – hassan May 13 '18 at 20:55
  • Sorry, that's a syntax error by me - will edit now. It is not an array in the actual program, just mistyped into stackoverflow. – Orbie May 13 '18 at 20:56
  • have you ever tried to dump this value `$date_unix`? – hassan May 13 '18 at 20:57
  • Yes, this value can be output using echo and just shows: 18/05/2018 – Orbie May 13 '18 at 20:57
  • sorry I mean , `$date_unix` – hassan May 13 '18 at 20:59
  • Yes I have, and nothing is dumped. I presume that shouldn't be the case, not sure why though. – Orbie May 13 '18 at 21:00
  • 1
    **Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed** http://php.net/manual/en/function.strtotime.php -- there is no month 18 even in 'merica –  May 13 '18 at 21:02
  • So i'd have to convert from my given format d/m/Y into m/d/Y? – Orbie May 13 '18 at 21:03

4 Answers4

1

From the strtotime documentation:

Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed

As 18/05/2018 is not a valid date in the American format (where the first number represents the month), your strtotime call will return false. And false (zero) will always be less than time().

The simplest fix, if you are confident about the format of the input, would be to replace the slashes with dashes before converting to timestamp. strtotime will then interpret the string as an international date which will work correctly:

$date = str_replace('/', '-', "18/05/2018");
$date_unix = strtotime($date);

However, updating your code to use the DateTime class, as in smith or LSerni's answers, will probably give you more flexibility going forward.

Tim Fountain
  • 33,093
  • 5
  • 41
  • 69
  • I've added some additional details. However, my original answer _did_ answer the question which was basically "why does this comparison not work?" – Tim Fountain May 14 '18 at 09:44
1

strtotime makes assumptions about the date format, and in this case those assumptions are wrong.

You are using a day/month/year format (like me: that's the default format in Italy). Yesterday, a date of 12/05/2018 would have been taken by strtotime, and assumed to be december 5th, 2018. The test would have been passed, and apparently been correct.

And if it had been a reservation, it would have incurred in seven months' worth of charges ;-D

So always specify the format. For that, I feel that the best is using DateTime:

 $date = date_create_from_format('d/m/Y', '18/05/2018');

for the same reasons, be wary how you calculate date differences.

(Also, be wary of Daylight Saving Time).

LSerni
  • 55,617
  • 10
  • 65
  • 107
0

should stop uing the legacy strtotime and start using the DateTime class

$date = "18/05/2018";

$newDate = DateTime::createFromFormat('d/m/Y', $date);

if (new DateTime() < $newDate) {
echo 'future';
}else{
echo 'past';
}
-1

To fix this problem, using information provided above I used the explode() to split up the $date variable into an array then rearrange the resulting array. I then pieced the exploded variables back together to form the correct American date format.

Below is the code relating to the above description:

$splitdate = (explode("/",$date));
$splitdate_day = $splitdate[0];
$splitdate_month = $splitdate[1];
$splitdate_year = $splitdate[2];

$date_change = $splitdate_month . "/" . $splitdate_day . "/" . $splitdate_year;

if(strtotime($date_change) < time()){
        echo '<b>Notice:</b> You cannot specify a date in the past.<br>';
    }

This may not be the most efficent method, but it solved the issue I was encoutering.

Orbie
  • 7
  • 5