-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[11.x] Introduce where[Date,Time,Year,Month,Day]Between
methods in query builder
#53105
base: 11.x
Are you sure you want to change the base?
Conversation
It would be nice, if this also supported enums out of the box: $articles = Post::whereMonthBetween('published_at', [
\Carbon\Month::January,
\Carbon\Month::March,
])->get();
$articles = Post::whereDayBetween('published_at', [
\Carbon\WeekDay::Monday,
\Carbon\WeekDay::Wednesday,
])->get(); |
This has been attempted before: #42261 See this important comment regarding indexes when using functions like |
I've seen that pull request and it lacks some functionality compared to this. Regarding to index, existing In my apps I have workaround using Here is the snippet in case someone is interested: (Works only on MySQL)<?php
use Carbon\CarbonPeriod;
use Illuminate\Database\Eloquent\Builder;
trait AdvancedDateFilters {
/**
* Filter timestamp/datetime column using casting
*
* @param Builder $query
* @param string $column
* @param DateTimeIterface|iterable<string|DateTimeIterface>|string $dates
* @return void
*/
public function scopeWhereTimestampDate(Builder $query, $column, $dates, $type = 'date') {
if($dates instanceof CarbonPeriod) {
$dates = [$dates->getStartDate(), $dates->getEndDate()];
}
if($dates instanceof DateTimeInterface) {
$dates = [$dates];
}
$dates = Arr::wrap($dates);
$query_interval = '';
[$date_format, $date_interval] = match($type) {
'date' => ['Y-m-d', 'day'],
'year' => ['Y', 'year'],
};
$dates = array_slice($dates, 0, 2);
// if only one date is provided, we will assume that it is the start and end date
if(count($dates) == 1) {
$dates[] = $dates[0];
$query_interval = ' + interval 1 ' . $date_interval;
}
$dates = collect($dates)->map(function($date) use ($date_format) {
return $date instanceof DateTimeInterface ? $date->format($date_format) : $date;
})->all();
$sql = sprintf("%s between cast(? as datetime) and cast(?%s as datetime)", $column, $query_interval);
return $query->whereRaw($sql, $dates);
}
} I can integrate this in this pull request if interested |
Definitelly can do this |
Added support for all default grammars.
Checking up this boxes brings up additional 15 functions in - Currently date functions don't support indexing, Solve that using casting Thank you. |
This could be solved with generated columns—to be convenient, these had to be auto-generated in a way preferably by using a trait, implementing an interface or a method on the return new class extends Migration
{
public function up(): void
{
Schema::create('table_with_dates', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->dateTimeTz('activated_at')->supportsDateWheres();
$table->timestamps();
});
}
}; |
…hereMonthBetween, orWhereDayBetween functions
…whereMonthNotBetween, whereDayNotBetween functions
Just finished adding more tests and I don't think there's need for I think at this state this pull request is ready for review and I'm ready for suggestions. |
@taylorotwell , please review and give me feedback if there's a need to add or change something. |
Since you now support |
Hello laravel team. This pull request was marked as "ready for review" 5 days ago. Can anyone tell me if this is missing something to start a review process? |
Added following methods to
Illuminate\Database\Query\Builder
class:whereDateBetween()
whereTimeBetween()
whereYearBetween()
whereMonthBetween()
whereDayBetween()
orWhereDateBetween()
orWhereTimeBetween()
orWhereYearBetween()
orWhereMonthBetween()
orWhereDayBetween()
whereDateNotBetween()
whereTimeNotBetween()
whereYearNotBetween()
whereMonthNotBetween()
whereDayNotBetween()
Eeach function works similar to existing
whereBetween
function andCarbonPeriod
as well.Usage examples:
orWhere[Date|Time|Year|Month|Day]Between
supportwhere[Date|Time|Year|Month|Day]NotBetween
supportAddorWhere[Date|Time|Year|Month|Day]NotBetween
supportCurrently date functions don't support indexing, Solve that using castingI hope you'll find this pull request helpful.
Any suggestions are welcome