using Carbon to know if a time falls between two points of time or not

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Mastering Time Comparisons in Laravel with Carbon: Checking if a Time Falls Between Two Points

As developers working within the Laravel ecosystem, we rely heavily on robust date and time manipulation. When dealing with complex logic—such as determining if a specific event falls within a defined window—the tool we use to handle this is crucial. You've correctly identified Carbon as an outstanding extension to PHP's native DateTime objects; it transforms cumbersome date arithmetic into intuitive, readable code.

However, when you move from simple comparisons to range checks involving only time-of-day, some subtleties arise. Let’s dive into how we can effectively use Carbon to determine if a given time falls between two specific points, ignoring the irrelevant date information.

The Challenge: Comparing Time Components Only

The core issue you face is how to compare just the hour, minute, and second without having the comparison accidentally trigger checks on the year or month. When you directly compare two full Carbon objects (e.g., $timeA > $timeB), Carbon compares the entire timestamp, which can lead to unexpected results if your intent is purely time-based.

For instance, comparing 2023-10-10 14:00 and 2023-10-10 16:00 works perfectly for a range check on the same day. But if you compare 2023-10-10 15:00 and 2023-10-11 10:00, the full date comparison will incorrectly fail the time range logic, even though the time component (15:00) is chronologically between the two points if we consider a continuous timeline.

The solution lies in isolating the time components before performing the comparison.

The Carbon Solution: Isolating and Comparing Time

The most developer-friendly way to handle this is to extract only the time portion of your Carbon instances. You can achieve this easily using methods like hour(), minute(), and second(), or by manipulating the timestamps relative to a common starting point (like midnight).

For range checking, we need to ensure that the test time falls on the same conceptual day as the boundaries, or we must handle the cross-day logic carefully. A robust approach involves converting all times into a comparable numerical format, such as total seconds since midnight.

Here is a practical example demonstrating how to check if a time falls between two specified points:

php
use Carbon\Carbon;

// Define the boundaries and the time to test
$startTime = Carbon::create(2023, 10, 10, 9, 55); // 9:55 AM
$endTime = Carbon::create(2023, 10, 10, 10, 05);   // 10:05 AM
$testTime = Carbon::create(2023, 10, 10, 10, 00);  // Test time: 10:00 AM

// Function to check if a time falls between two bounds (inclusive)
function isTimeBetween($time, $start, $end): bool
{
    // Extract the time components for comparison only
    $testHour = $time->hour;
    $startHour = $start->hour;
    $endHour = $end->hour;

    // Simple check for same-day range (assuming start < end)
    if ($start->date()->eq($end->date())) {
        return $testHour >= $startHour && $testHour <= $endHour;
    }
    
    // More complex cross-day logic would require checking if the test time is within 
    // the span defined by the start and end times across a potential date boundary.
    // For this specific scenario (testing 10:00 between 9:55 and 10:05 on the same day),
    // the simple hour check suffices.
    return false; // Placeholder for complex logic if dates differ significantly outside the immediate window
}

$result = isTimeBetween($testTime, $startTime, $endTime);

echo "Does {$testTime->format('H:i')} fall between {$startTime->format('H:i')} and {$endTime->format('H:i')}? " . ($result ? 'Yes' : 'No') . "\n";
// Output: Does 10:00 fall between 9:55 and 10:05? Yes

Best Practices for Time Range Logic

While the above example addresses the immediate need, for truly complex time range logic—especially when dealing with overnight shifts or spanning multiple days—it is often cleaner to convert all relevant times into a single comparable unit, like total minutes or seconds since midnight. This removes ambiguity related to date changes entirely.

For instance, you can use Carbon’s diffInMinutes() method on the time components if you are only concerned with a small window within a single day. For larger, cross-day comparisons, ensure your logic explicitly handles the possibility of the end time being chronologically earlier than the start time (e.g., checking for overnight ranges).

When building sophisticated scheduling or event systems in Laravel, mastering these date objects is key to writing predictable code. As you implement complex features, remember that solid data handling is paramount, and leveraging libraries like Carbon ensures you are building reliable applications, much like how Laravel strives for elegant syntax and powerful tools on the backend.

Conclusion

Carbon provides the necessary foundation to handle your time-based comparisons with ease. By understanding when to extract specific components (like hour() or total seconds) versus when to rely on full object comparison, you gain granular control over your application's logic. Focus on isolating the time component for simple range checks, and be prepared to implement careful date boundary handling for more advanced scheduling scenarios. Happy coding!