In the most simplest terms this is a PHP function that will tell you if a given time is between a given start and end time, even if the span crosses midnight. In other words, it answers the question is 3 AM is between 2020-12-01 11 PM and 2020-12-02 6 AM?. Arriving at the correct answer is more complicated than one would expect. Hopefully the solution shown here comes across as simple.
Function Definition
The function returns true if the time component of a PHP DateTimeInterface object falls within two other DateTimeInterface objects, regardless of what the date components of all the objects are. For example, you want to know if 3:00 AM is between December 31, 2020 11:00 PM and January 1, 2021 6:00 AM?
<?php/** * Check if a given $time is between the hours of $start and $end * Works even if the interval crosses midnight * * @param \DateTimeImmutable $time * @param \DateTimeImmutable $start * @param \DateTimeImmutable $end * @return bool * * @author Daniel Morante <daniel@morante.net> */function BetweenHours(\DateTimeImmutable $time, \DateTimeImmutable $start, \DateTimeImmutable $end): bool { // Neutralize the date component to test if the span between $start and $time crosses midnight $normalized_start = \DateTime::createFromImmutable($start); $normalized_start->setDate($time->format('Y'), $time->format('m'), $time->format('d')); // Test if the $time crosses midnight. If it does anchor the date of $normalized_time to that of $end $anchor = ($time < $normalized_start) ? clone $end : clone $start; // Set the date to the selected anchor, keeping the time $normalized_time = \DateTime::createFromImmutable($time); $normalized_time->setTimezone($anchor->getTimezone()); $normalized_time->setDate($anchor->format('Y'), $anchor->format('m'), $anchor->format('d')); // Finally, answer the question is $time between $start and $end? return ($normalized_time >= $start && $normalized_time <= $end);}?>
Usage Example
Create your DateTimeImmutable objects and pass them to the function.
<?php$start_time = new DateTimeImmutable("2020-12-31 11:00 PM");$end_time = new DateTimeImmutable("2021-1-1 6:00 AM");$current_time = new DateTimeImmutable("3:00 AM");printf("Is %s between %s and %s?" . PHP_EOL, $current_time->format('H:i'), $start_time->format('H:i'), $end_time->format('H:i'));echo BetweenHours($current_time, $start_time, $end_time) ? 'Yes' : 'No'; echo PHP_EOL;?>
- Log in to post comments