65

I just want to compare 2 datetime objects to see if they are set to the same date, but I don't care about the time component of the the object. At the moment I am using the date_format command to extract strings like 'Y-m-d' to compare but this seems awkward.

$firstDate = date_format($firstDateTimeObj, 'Y-m-d');
$secondDate = date_format($secondDateTimeObj, 'Y-m-d');

if !($firstDate == $secondDate) {

// some code
}

I'm new to programming and PHP so any pointers appreciated.

Dave Shaw
  • 649
  • 1
  • 5
  • 3
  • 3
    I'm sure that someone will come up with some clever manipulation of timestamps or something like that, but truly you've got the gist of it. Sorry that it's awkward... – Brian Driscoll Nov 30 '11 at 15:32
  • 1
    Unfortunately PHP doesn't have a "gimme just the date" formatting option, so what you're doing is the best option. – Marc B Nov 30 '11 at 15:44
  • What's wrong with it? Is it causing you an error? The only enhancement I can suggest would be to use the format() method on the objects directly. – liquorvicar Nov 30 '11 at 16:06
  • Cheers. At least I'm now confident that I'm not unnecessarily complicating matters - PHP is doing that for me ;-) – Dave Shaw Nov 30 '11 at 18:03

10 Answers10

75

Use the object syntax!

$firstDate = $firstDateTimeObj->format('Y-m-d');
$secondDate = $secondDateTimeObj->format('Y-m-d');

You were very close with your if expression, but the ! operator must be within the parenthesis.

if (!($firstDate == $secondDate))

This can also be expressed as

if ($firstDate != $secondDate)
Evert
  • 93,428
  • 18
  • 118
  • 189
  • 13
    By this way, you will not able to compare date (<, <=, > ...) – TeChn4K Nov 30 '11 at 15:42
  • 3
    @TeChn4K: With DateTime objects, you *will* be. – Amal Murali Mar 04 '14 at 19:22
  • 1
    And here's a link to the PHP documentation about comparing DateTime objects with `<`, `==` etc: http://php.net/manual/en/datetime.diff.php#example-2364. Of course, it doesn't solve the "ignoring time" part of the problem - set the times on both DateTime objects to be the same before comparing to solve that one. – Sam Aug 21 '14 at 13:41
  • 2
    You can also `$diff=($d1->format("Ymd")-$d2->form("Ymd"))`. Its more consise. – Andreas Dyballa Oct 26 '15 at 12:10
  • @TeChn4K: please careful! ->format('Y-m-d') is for sure string - not DateTime - so $firstDate == $secondDate is a string comparison! – Hauke Sep 18 '18 at 12:14
  • 2
    You **can** accurately compare `Y-m-d` formatted dates with any [comparison operator](https://www.php.net/manual/en/language.operators.comparison.php), since the PHP lexer interprets the values appropriately when the day and month have leading zeros. It is the equivalent of using [`strcmp('A10', 'A02')`](https://www.php.net/manual/en/function.strcmp.php) and how `sort` works on strings.. Example: https://3v4l.org/BfI00 However, you cannot accurately compare `Y-n-j` formatted dates, due to missing the leading zeros. IE `"A10" > "A2" = false`, use `strnatcmp('A10', 'A2') > 0` instead. – Will B. Dec 01 '19 at 20:57
17

My first answer was completely wrong, so I'm starting a new one.

The simplest way, as shown in other answers, is with date_format. This is almost certainly the way to go. However, there is another way that utilises the full power of the DateTime classes. Use diff to create a DateInterval instance, then check its d property: if it is 0, it is the same day.

// procedural
$diff = date_diff($firstDateTimeObj, $secondDateTimeObj);

// object-oriented
$diff = $firstDateTimeObj->diff($secondDateTimeObj);

if ($diff->format('%a') === '0') {
    // do stuff
} else {
    // do other stuff
}

Note that this is almost certainly overkill for this instance, but it might be a useful technique if you want to do more complex stuff in future.

you786
  • 3,659
  • 5
  • 48
  • 74
lonesomeday
  • 233,373
  • 50
  • 316
  • 318
  • Maybe can you make clear "d" attribute ? (m : month; d, day; h, hour; i, minute; s, second;) – TeChn4K Dec 01 '11 at 09:12
  • 16
    Actually this will not work in all cases. It is only effective if you are absolutely sure that both DateTime objects have the same time. Ex: If you have 2 date times, one with the time set to 2/11/2012 at 22:00:00 and the other set to 2/12/2012 at 20:00:00 it will be read as having the same day as there is less then 24 hours separating the times. – William King Feb 12 '12 at 08:02
  • 1
    Coorect me if I'm wrong but this would not work if the datetime objects are separately by whole months. Ex: `2013-01-25 00:00:00` and `'2013-02-25 00:00:00'` – Cesar Jun 21 '13 at 15:28
  • @Cesar You are entirely right. `format('a')` is the correct code, I think. – lonesomeday Jun 21 '13 at 15:30
  • 3
    @lonesomeday Your format string is wrong, DateInterval format requires before the format character. It should be `format('%a')` – VanTanev Jul 08 '13 at 18:31
  • 4
    This will also fail if the one date time is '2014-03-28 10:00' and the other is '2014-03-27 17:00'. There are less than twenty four hours apart and so the interval will only show a different of hours. – Alexander Garden Mar 28 '14 at 19:30
15

Searching for an answer with the same problem.. I arrived to this solution that's look better for me then use diff or other things.

The main problem was ignoring the time parts of object DateTime, just set it to a time, for example at 12:00:00

$firstDateTimeObj->setTime(12, 0, 0);
$secondDateTimeObj->setTime(12, 0, 0);

// The main problem was checking if different.. but you can use any comparison
if ($firstDateTimeObj != $secondDateTimeObj) {
}
Massimo
  • 553
  • 7
  • 24
  • best answer, which allows to check if a date is superior or inferior to another one. I think doing `setTime(12, 0)` is enough though, seconds and microseconds will automatically be set to 0. – Roubi Mar 25 '19 at 18:35
  • 8
    BE CAREFUL! `$DateTimeObj->setTime(12, 0, 0);` will modify your original DateTime Object! If you want to follow this approach, you should `clone` the DateTime Objects first, then modify times and compare cloned objects. – Alberto Jul 10 '19 at 08:20
  • Important: If the two objects have a different time zone, then they will not be considered equal. This may or may not be what you want. – jlh May 04 '20 at 08:07
12

I think your approach is good, but I would remove the - as they do not add anything.

$firstDate = date_format($firstDateTimeObj, 'Ymd');
$secondDate = date_format($secondDateTimeObj, 'Ymd');

if ($firstDate != $secondDate) {
    // some code
}
Wesley van Opdorp
  • 14,888
  • 4
  • 41
  • 59
  • As Evert, it is correct only for this condition. If you compare those dates, it will be on string type. strtotime is theoretically a better way to compare. – TeChn4K Nov 30 '11 at 15:51
  • Theoretically - Yes, I agree. But this is very practical - and with type juggling this also works for < > comparisons. I wouldn't advice any overkill comparisons on this easy case. – Wesley van Opdorp Nov 30 '11 at 16:02
  • I think everybody should advice best practice. PHP is a loosely typed language, and the best one to take bad habits – TeChn4K Nov 30 '11 at 16:09
6

This worked great for me.

$date1=DateTime::createFromFormat('Y-m-d H:i:s', '2014-07-31 07:30:00')->format('Y-m-d');
$date2=DateTime::createFromFormat('Y-m-d H:i:s', '2014-08-01 17:30:00')->format('Y-m-d');
if($date1==$date2){
    echo "==";
}else{
    echo "!=";
}
itsazzad
  • 6,868
  • 7
  • 69
  • 89
4

Looking here for the same question and came up with another way to do it. Fairly concise:

$diff = date_diff($date1,$date2);
if ($diff->days == '0') {
  /* it's the same date */
}

First get a date_interval object using date_diff. The date_interval object has a property for 'days' which you can use to get the total number of days between the two dates.

I'm using this to compare today to registration dates and send emails at specific time intervals based on how long they have been a member.

Don Bryn
  • 67
  • 3
  • 5
    this is actualy wrong. you check if there is a day in between these two dates, but not if this are two different days. try comparing 1970-12-12T23:00 and 1970-12-13T00:00. two different days but the interval is less than a day. – anonym-developer Apr 24 '19 at 10:51
  • In other words, this works if you need to compare DAYS but not if you need to compare anything less that a day. Since the original question specifically wants to know if it’s the same day and ignore time, this works. – Don Bryn Apr 25 '19 at 11:46
  • @DonBryn actually, it's not ignoring time. Something at 23:50 on 2019-01-01 compared to 01:15 on 2019-01-02 would return true. The difference is less than 1 whole day, so $diff->days will return 0. I've tested this to be certain. – Tim Ogilvy Aug 12 '19 at 06:01
-1

Quick and dirty, reusable with as many dates as you like, may still need some adjusting:

update: less dirty.

if(sameDate($firstDateTimeObj, $secondDateTimeObj, $ThirdDateTimeObj))
{
   // your code

}

function sameDate (DateTime ...$dates) {

   foreach($dates as $date)
   {
      $test[] = $date->format('Ymd');
   }

   $result = array_unique($test);

   if(count($result) == 1)
   {
      return true;
   {

   return false;

}
Jonathan Joosten
  • 1,499
  • 12
  • 12
-1

strtotime convert a textual date into a Unix timestamp : http://fr.php.net/manual/en/function.strtotime.php

$first = strtotime(date_format($firstDateTimeObj, 'Y-m-d'));
$second = strtotime(date_format($secondDateTimeObj, 'Y-m-d'));

if ($first != $second) {

// some code
}

And also :

if ($first > $second) {
// some code
}

if ($first < $second) {
// some code
}
TeChn4K
  • 2,317
  • 2
  • 21
  • 23
-1
$first = strtotime(date_format($firstDateTimeObj, 'Y-m-d'));
$second = strtotime(date_format($secondDateTimeObj, 'Y-m-d'));

if ($first != $second) {
    // some code
}
Dmitriy Simushev
  • 308
  • 1
  • 16
-2

Initialise a DateTime object and set the time to 00:00:00. Then you can use any comparison between dates ignoring the times:

$today = \DateTime::createFromFormat('d/m/Y H:i:s', '21/08/2014 00:00:00');
$tomorrow = \DateTime::createFromFormat('d/m/Y H:i:s', '22/08/2014 00:00:00');

// now you can compare them just with dates
var_dump($today < $tomorrow); //true
var_dump($today === $tomorrow); //false
var_dump($today !== $tomorrow); //true

@Evert's answer works fine, but it looks like really wrong to transform a DateTime object into a string and then compare them.

romulodl
  • 91
  • 1
  • 1
  • 7
  • 1
    `$today !== $tomorrow;` will always be true as `$today` and `$tomorrow` are different instances. And `$today === $tomorrow;` will always be false, even if the second parameters are the same. – thomas-hiron Jun 26 '18 at 10:27