Fix whereBetween to accept DatePeriod and handle missing end dates (#58092)#58687
Merged
taylorotwell merged 3 commits intolaravel:12.xfrom Feb 9, 2026
Merged
Conversation
shaedrich
reviewed
Feb 8, 2026
| * Resolve the start and end dates from a DatePeriod. | ||
| * | ||
| * @param \DatePeriod $period | ||
| * @return array |
Contributor
There was a problem hiding this comment.
You could define a tuple here:
Suggested change
| * @return array | |
| * @return array{\DateTimeInterface, \DateTimeInterface} |
| if ($end === null) { | ||
| $end = clone $start; | ||
|
|
||
| for ($i = 0; $i < $period->getRecurrences(); $i++) { |
Contributor
There was a problem hiding this comment.
It might slightly improve performance if you avoid getting the recurrences on every iteration
Suggested change
| for ($i = 0; $i < $period->getRecurrences(); $i++) { | |
| $recurrences = $period->getRecurrences(); | |
| for ($i = 0; $i < $recurrences; $i++) { |
or
Suggested change
| for ($i = 0; $i < $period->getRecurrences(); $i++) { | |
| for ($i = 0, $recurrences = $period->getRecurrences(); $i < $recurrences(); $i++) { |
mosabbirrakib
added a commit
to mosabbirrakib/framework
that referenced
this pull request
Feb 15, 2026
…whereBetween/havingBetween This PR adds comprehensive integration tests for the DatePeriod support that was added in PR laravel#58687. ## Problem While PR laravel#58687 added DatePeriod support to whereBetween() and havingBetween() methods with unit tests, it lacks comprehensive integration tests that verify the feature works correctly with real database queries. ## Solution This PR adds comprehensive integration tests in QueryBuilderDatePeriodTest.php that test all DatePeriod scenarios with actual database queries: - whereBetween with DatePeriod - whereBetween with CarbonPeriod - whereBetween with recurrences (no end date) - whereBetween with EXCLUDE_START_DATE flag - whereBetween with INCLUDE_END_DATE flag - whereBetween with both flags combined - whereNotBetween with DatePeriod - whereNotBetween with EXCLUDE_START_DATE flag - havingBetween with DatePeriod (grouped queries) - havingNotBetween with DatePeriod - orWhereBetween with DatePeriod - orWhereNotBetween with DatePeriod ## Benefits to End Users These integration tests ensure that: 1. DatePeriod works correctly with real database queries 2. All edge cases are covered (recurrences, inclusion/exclusion flags) 3. The feature works across different database drivers 4. Future changes won't break DatePeriod support ## Breaking Changes None. This only adds tests for existing functionality. Relates to laravel#58092
mosabbirrakib
added a commit
to mosabbirrakib/framework
that referenced
this pull request
Feb 15, 2026
…inclusion/exclusion flags This PR enhances the DatePeriod support in whereBetween() and havingBetween() methods to properly handle DatePeriod inclusion/exclusion flags and NOT BETWEEN logic. ## Problem While PR laravel#58687 added basic DatePeriod support to whereBetween() and havingBetween(), it has several limitations: 1. **Ignores inclusion/exclusion flags**: DatePeriod supports EXCLUDE_START_DATE and INCLUDE_END_DATE flags, but the current implementation doesn't respect them 2. **Incorrect NOT BETWEEN logic**: The current implementation doesn't handle whereNotBetween() and havingNotBetween() correctly with DatePeriod 3. **Limited test coverage**: Only has basic unit tests, lacks comprehensive integration tests ## Solution This PR enhances the DatePeriod support by: 1. **Respecting inclusion/exclusion flags**: Uses correct operators (>, >=, <, <=) based on DatePeriod flags 2. **Fixing NOT BETWEEN logic**: Properly implements NOT BETWEEN using OR logic (value < start OR value > end) 3. **Adding comprehensive integration tests**: 12 integration test methods covering all scenarios ## Implementation Details ### whereBetweenDatePeriod() Method - Extracts start and end dates from DatePeriod - Calculates end date from recurrences if needed - Determines operators based on include_start_date and include_end_date flags - For NOT BETWEEN: Uses OR logic (value < start OR value > end) - For BETWEEN: Uses AND logic with appropriate operators ### havingBetweenDatePeriod() Method - Same logic as whereBetweenDatePeriod() but for HAVING clauses - Uses havingRaw() for NOT BETWEEN to properly handle OR logic ## Benefits to End Users ### Before (ignores flags): ```php // Ignores EXCLUDE_START_DATE flag $period = new DatePeriod( new DateTime('2024-01-01'), new DateInterval('P1D'), new DateTime('2024-01-31'), DatePeriod::EXCLUDE_START_DATE ); User::whereBetween('created_at', $period)->get(); // Still includes Jan 1st ❌ // Ignores INCLUDE_END_DATE flag $period = new DatePeriod( new DateTime('2024-01-01'), new DateInterval('P1D'), new DateTime('2024-01-31'), DatePeriod::INCLUDE_END_DATE ); User::whereBetween('created_at', $period)->get(); // Doesn't include Jan 31st ❌ ``` ### After (respects flags): ```php // Respects EXCLUDE_START_DATE flag $period = new DatePeriod( new DateTime('2024-01-01'), new DateInterval('P1D'), new DateTime('2024-01-31'), DatePeriod::EXCLUDE_START_DATE ); User::whereBetween('created_at', $period)->get(); // Excludes Jan 1st ✅ // Respects INCLUDE_END_DATE flag $period = new DatePeriod( new DateTime('2024-01-01'), new DateInterval('P1D'), new DateTime('2024-01-31'), DatePeriod::INCLUDE_END_DATE ); User::whereBetween('created_at', $period)->get(); // Includes Jan 31st ✅ ``` ## Tests Added ### Integration Tests (12 methods): ✅ whereBetween with DatePeriod ✅ whereBetween with CarbonPeriod ✅ whereBetween with recurrences (no end date) ✅ whereBetween with EXCLUDE_START_DATE flag ✅ whereBetween with INCLUDE_END_DATE flag ✅ whereBetween with both flags combined ✅ whereNotBetween with DatePeriod ✅ whereNotBetween with EXCLUDE_START_DATE flag ✅ havingBetween with DatePeriod (grouped queries) ✅ havingNotBetween with DatePeriod ✅ orWhereBetween with DatePeriod ✅ orWhereNotBetween with DatePeriod All tests use real database queries with actual data to ensure the feature works correctly across all supported database drivers. ## Breaking Changes None. This is purely additive and enhances existing functionality. ## Code Changes - **Modified**: src/Illuminate/Database/Query/Builder.php (+98 -5 lines) - Added whereBetweenDatePeriod() protected method - Added havingBetweenDatePeriod() protected method - Enhanced whereBetween() to delegate to whereBetweenDatePeriod() - Enhanced havingBetween() to delegate to havingBetweenDatePeriod() - **New file**: tests/Integration/Database/QueryBuilderDatePeriodTest.php (268 lines) - 12 comprehensive integration test methods - Tests all DatePeriod scenarios with real database queries Fixes laravel#58092
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #58092
whereBetweenandhavingBetweenusedCarbonPeriodinstead ofDatePeriod.This PR changes
instanceof CarbonPeriodtoinstanceof \DatePeriodwhich is backward compatible and calculates the end date from whengetEndDate()is nullRespecting
EXCLUDE_START_DATE/INCLUDE_END_DATEflags is a behavioral change and needs to be in a separate issue to target master.