9

If I have two date ranges (e.g. May 1 - May 31 and May 23 - June 5) what would be the best way to find out how many days the two periods overlap in PHP (so it would return 9)? Is there a way to do this using DatePeriod objects?

Edit to (hopefully) clarify my question:

Basically I want a function that, given any two date ranges, will return the number of days that are common between both date ranges. If there is an overlap it will return the number of overlapping days, otherwise it will return 0. I thought this could be done by making an array of dates for each range, looping through them to find identical dates, and using a variable to count the number of matches - but I am looking for something more elegant.

Dustin
  • 707
  • 1
  • 7
  • 11
  • Sorry, I should have been more clear. I figure I could probably make an array of dates for each range, loop through them to find identical dates, and use a variable to count the number of matches. It seems like this might be overly complicated though if there is a more basic way to do this with DatePeriod. I know you can calculate the difference between two dates using DateTime->diff, so I though there might be something similar for DatePeriod, but I'm not having much luck on Google. Maybe something like `$dateperiod->diff($dateperiod2)`. – Dustin Jan 07 '13 at 20:01
  • Okay, this question has been downvoted and closed, which is fine. But what can I do to stop being downvoted? – Dustin Jan 11 '13 at 22:18

2 Answers2

40

Thanks to @phpisuber01 and Determine Whether Two Date Ranges Overlap for providing the basic logic here. The four variables need to be DateTime objects:

function datesOverlap($start_one,$end_one,$start_two,$end_two) {

   if($start_one <= $end_two && $end_one >= $start_two) { //If the dates overlap
        return min($end_one,$end_two)->diff(max($start_two,$start_one))->days + 1; //return how many days overlap
   }

   return 0; //Return 0 if there is no overlap
}
Community
  • 1
  • 1
Dustin
  • 707
  • 1
  • 7
  • 11
  • 7
    to be complete, also use the other way around: if (($start_one <= $end_two && $end_one >= $start_two) || ($start_two <= $end_one && $end_two >= $start_one) ){ ... } – eddy147 Oct 20 '14 at 18:59
  • 1
    The above comment is incorrect you do not need two conditions. – morphles Oct 29 '20 at 11:52
1

Without any real information to base this on.. Here is a basic example of how to calculate a difference of days using the DateTime object.

$datetime1 = new DateTime('2013-05-23');
$datetime2 = new DateTime('2013-05-31');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days'); //returns 8 days

I assume you know how to convert your strings there into usable timestamps/formats.

phpisuber01
  • 7,585
  • 3
  • 22
  • 26
  • 1
    Yes, I already know how to compare two dates. What I want is something to compare two date ranges or DatePeriods. i.e. how much does $dateperiod1 overlap with $dateperiod2? – Dustin Jan 07 '13 at 20:02
  • @Dustin All you need to do is get the last date in your first range and the first date in your last range and compare. Boom. – phpisuber01 Jan 07 '13 at 20:06
  • Thanks. That works in the example I gave, but I should have also mentioned that while one of the ranges is preset, the other one is set by the user, so there may be no overlap at all. In that case comparing the last date in one range with the first date in the other would give a positive number when it should return 0. – Dustin Jan 07 '13 at 20:13
  • @Dustin Without having all the information there is no way for someone to give you an answer. You should update your question with all these details and your attempt. Some simple logic will resolve any concern you may have with unreal date intervals. – phpisuber01 Jan 07 '13 at 20:15
  • Yup, I don't know why I'm having so much trouble writing my questions today. I think maybe because the actual answer is different then what I was expecting, but even then I apologize for not being anywhere near detailed and clear enough. I think your tips have me well on my way to figuring something out, so thanks for your patience. Once I get it figured out I will edit my question and post my solution. – Dustin Jan 07 '13 at 20:44