Reputation: 2683
I have two Datetimes like this (the dates being actually $vars)
$startTime = \DateTime::createFromFormat('Y/m/d H:i', '2015/01/01 23:00');
$endTime = \DateTime::createFromFormat('Y/m/d H:i', '2015/01/02 01:00');
I struggle with a (possibly pretty) simple problem: How could I determine if the two dates are on different calendar days?
I cannot do <
as 2015/01/01 22:00 < 2015/01/01 23:00
would also be true. I can also not do this:
$diff = $startTime->diff($endTime);
$days = $diff->format('%d');
echo $days;
as it gives me 0
.
THIS gives me an idea about how to do it, but for javascript, what would be the equivalent for php?
//UPDATE
$startDate = $startTime->format('Y/m/d');
$endDate = $endTime->format('Y/m/d');
$diffDates = $startDate->diff($endDate);
$daysDiff = $diffDates->format('%d');
echo $daysDiff;
I think that might be the right approach now, thanks to the comments, but now I get Error: Call to a member function diff() on string
//UPDATE FOR CLARIFICATION WHAT I'M TRYING TO DO
I just want to have the difference in days, so for the above it would be '1'
(although only 2 hours difference actually) and for example '2015/01/01 23:00' and '2015/01/03 17:00'
would be '2'
.
Upvotes: 3
Views: 4427
Reputation: 5056
Comparing formatted dates is the right thing to do:
$a->format('Y-m-d') === $b->format('Y-m-d')
There is a method for that if you use Carbon:
$dt1->isSameDay($dt2)
So I recommend to use it instead of previous answers given here.
http://carbondoc/docs/#api-comparison
Upvotes: 2
Reputation: 146390
I think this is one of the few situations where the use of strings for date calculations is justified:
function onDifferentDays(\DateTimeInterface $startTime, \DateTimeInterface $endTime){
return $startTime->format('Y-m-d')!==$endTime->format('Y-m-d');
}
This code should be easy to extend to include time zone.
There're other alternatives but I don't think they're normally worth the effort:
Compare element by element (day, month and year):
DateTime
class doesn't offer dedicated functions, only format()
.Normalize both dates to a common time and compare with ==
(not ===
):
Unless you're using immutable objects you need to clone input or expect side effects
You also need to ensure that time exists in the active time zone though midnight is probably safe enough.
Whatever, YMMV ;-)
Upvotes: 3
Reputation: 2844
Just create the dates with time set to 00:00:00:
$startTime = \DateTime::createFromFormat('Y/m/d H:i:s', '2015/01/01 00:00:00');
$endTime = \DateTime::createFromFormat('Y/m/d H:i:s', '2015/01/02 00:00:00');
or reset time to zero on existing dates:
$startTime->setTime(0, 0, 0);
$endTime->setTime(0, 0, 0);
then it should work:
$diff = $startTime->diff($endTime);
$days = $diff->format('%d');
echo $days; // 1
Bonus
If you want to work only with dates, remember to set the time to 00:00:00 in createFromFormat
or reset it with setTime
. If you won't provide time in createFromFormat
PHP will set it to the current time:
$date = DateTime::createFromFormat('Y-m-d', '2016-01-21');
print $date->format('H:i:s'); //not 00:00:00
To fix it, you must either:
provide 00:00:00 time in format:
$date = DateTime::createFromFormat('Y-m-d H:i:s', '2016-01-21 00:00:00');
prefix the date format with exclamation mark and omit the time, this will set the time to 00:00:00 automatically:
$date = DateTime::createFromFormat('!Y-m-d', '2016-01-21');
reset the time after creation:
$date = DateTime::createFromFormat('Y-m-d', '2016-01-21');
$date->setTime(0, 0);
Upvotes: 3