255

I'm trying to create a report page that shows reports from a specific date to a specific date. Here's my current code:

$now = date('Y-m-d');
$reservations = Reservation::where('reservation_from', $now)->get();

What this does in plain SQL is select * from table where reservation_from = $now.

I have this query here but I don't know how to convert it to eloquent query.

SELECT * FROM table WHERE reservation_from BETWEEN '$from' AND '$to

How can I convert the code above to eloquent query?

3
  • what is the date format in reservation_from. you can use the Carbon values based on that. Commented Oct 27, 2015 at 7:00
  • date format is TIMESTAMP @AthiKrishnan
    – wobsoriano
    Commented Oct 27, 2015 at 7:01
  • 4
    it would be like, Reservation::where('reservation_from', '>=', Carbon::createFromDate(1975, 5, 21);) ->where('reservation_from', '<=', Carbon::createFromDate(2015, 5, 21);)->get(); Commented Oct 27, 2015 at 7:02

15 Answers 15

483

The whereBetween method verifies that a column's value is between two values.

$from = date('2018-01-01');
$to = date('2018-05-02');

Reservation::whereBetween('reservation_from', [$from, $to])->get();

In some cases you need to add date range dynamically. Based on @Anovative's comment you can do this:

Reservation::all()->filter(function($item) {
  if (Carbon::now()->between($item->from, $item->to)) {
    return $item;
  }
});

If you would like to add more condition then you can use orWhereBetween. If you would like to exclude a date interval then you can use whereNotBetween .

Reservation::whereBetween('reservation_from', [$from1, $to1])
  ->orWhereBetween('reservation_to', [$from2, $to2])
  ->whereNotBetween('reservation_to', [$from3, $to3])
  ->get();

Other useful where clauses: whereIn, whereNotIn, whereNull, whereNotNull, whereDate, whereMonth, whereDay, whereYear, whereTime, whereColumn , whereExists, whereRaw.

Laravel docs about Where Clauses.

8
  • How would this be handled if the $from and $to would be dynamic dates that belong to the model? As in there is an effective_at and expires_at fields and I want to query to see if the current item is within that range. I tried each() with an if that uses Carbon::now()->between( ... ), however it still returns all results. Commented Feb 5, 2019 at 19:27
  • 5
    EDIT for my above comment: Overlooked filter(), that did the trick. MyModel::all()->where('column', 'value')->filter(function ($item) { if (Carbon::now->between($item->effective_at, $item->expires_at)) { return $item; } })->first(); Commented Feb 5, 2019 at 19:34
  • 1
    @Anovative thanks for your useful comment. I'll update my answer based on your comment.
    – Peter Kota
    Commented Feb 5, 2019 at 19:40
  • it will only give from date record.
    – Muhammad
    Commented Feb 20, 2020 at 1:24
  • 3
    There is a problem with the second method. It will load all records from DB to memory and then only it will perform the filtering. Commented Jun 29, 2020 at 12:26
30

And I have created the model scope

To Know More about scopes check out the below links:

Code:

   /**
     * Scope a query to only include the last n days records
     *
     * @param  \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeWhereDateBetween($query,$fieldName,$fromDate,$todate)
    {
        return $query->whereDate($fieldName,'>=',$fromDate)->whereDate($fieldName,'<=',$todate);
    }

And in the controller, add the Carbon Library to top

use Carbon\Carbon;

To get the last 10 days record from now

 $lastTenDaysRecord = ModelName::whereDateBetween('created_at',(new Carbon)->subDays(10)->startOfDay()->toDateString(),(new Carbon)->now()->endOfDay()->toDateString() )->get();

To get the last 30 days record from now

 $lastThirtyDaysRecord = ModelName::whereDateBetween('created_at',(new Carbon)->subDays(30)->startOfDay()->toDateString(),(new Carbon)->now()->endOfDay()->toDateString() )->get();
3
  • 1
    WhereDateBetween second param needs to be an array.
    – Dr. House
    Commented Jan 16, 2020 at 11:32
  • It's just a scope of the model it's not Builder method
    – ManojKiran
    Commented Jan 17, 2020 at 6:43
  • Oh yeah, missed that somehow. My bad:)
    – Dr. House
    Commented Jan 17, 2020 at 14:27
26

Another option if your field is datetime instead of date (although it works for both cases):

$fromDate = "2016-10-01";
$toDate = "2016-10-31";

$reservations = Reservation::whereRaw(
  "(reservation_from >= ? AND reservation_from <= ?)", 
  [
     $fromDate ." 00:00:00", 
     $toDate ." 23:59:59"
  ]
)->get();
4
  • 1
    technically wouldn't it need to be $toDate . " 23:59.59.999" ? Commented Sep 12, 2018 at 11:27
  • @stevepowell2000 It depends on your database, in my case we store the date with this format 'YYYY-MM-DD HH:MM:SS' in a datetime mysql field, without microseconds precision. Related info: dev.mysql.com/doc/refman/8.0/en/datetime.html
    – tomloprod
    Commented Sep 12, 2018 at 12:20
  • Great point. So if it was a datetime or timestamp field we may to go all the way out to 23:59:59.999999 "A DATETIME or TIMESTAMP value can include a trailing fractional seconds part in up to microseconds (6 digits) precision." Commented Sep 12, 2018 at 14:00
  • 1
    thank you you've been help me to do my task before! love this answer bro! :) -habie Commented Jan 16, 2020 at 7:21
24

If you want to check if current date exist in between two dates in db: =>here the query will get the application list if employe's application from and to date is exist in todays date.

$list=  (new LeaveApplication())
            ->whereDate('from','<=', $today)
            ->whereDate('to','>=', $today)
            ->get();
0
18

The following should work:

$now = date('Y-m-d');
$reservations = Reservation::where('reservation_from', '>=', $now)
                           ->where('reservation_from', '<=', $to)
                           ->get();
13

If you need to have in when a datetime field should be like this.

return $this->getModel()->whereBetween('created_at', [$dateStart." 00:00:00",$dateEnd." 23:59:59"])->get();
1
  • 2
    Hi, welcome to Stack Overflow. When answering a question that already has many answers, please be sure to add some additional insight into why the response you're providing is substantive and not simply echoing what's already been vetted by the original poster. This is especially important in "code-only" answers such as the one you've provided.
    – chb
    Commented Apr 25, 2019 at 20:33
12

Try this:

Since you are fetching based on a single column value you can simplify your query likewise:

$reservations = Reservation::whereBetween('reservation_from', array($from, $to))->get();

Retrieve based on condition: laravel docs

Hope this helped.

1
  • 2
    Be careful if you want a register from 1 of feb 2021 to 31 may 2021 and this register was created at 31 may 2021 it will not work, in that case you should use this: whereDate('created_at', '>=', $this->start_date) ->whereDate('created_at', '<=', $this->end_date) ->get() Commented Jul 19, 2021 at 23:15
6

I followed the valuable solutions provided by other contributors and faced a minor issue no one has addressed. If the reservation_from is a datetime column then it might not produce results as expected and will miss all the records in which the date is same but time is anything above 00:00:00 time. To improve the above code a bit a small tweak is needed like so.

$from = Carbon::parse();
$to = Carbon::parse();
$from = Carbon::parse('2018-01-01')->toDateTimeString();
//Include all the results that fall in $to date as well
$to = Carbon::parse('2018-05-02')
    ->addHours(23)
    ->addMinutes(59)
    ->addSeconds(59)
    ->toDateTimeString();
//Or $to can also be like so
$to = Carbon::parse('2018-05-02')
    ->addHours(24)
    ->toDateTimeString();
Reservation::whereBetween('reservation_from', [$from, $to])->get();
4

I know this might be an old question but I just found myself in a situation where I had to implement this feature in a Laravel 5.7 app. Below is what worked from me.

 $articles = Articles::where("created_at",">", Carbon::now()->subMonths(3))->get();

You will also need to use Carbon

use Carbon\Carbon;
2

Let me add proper syntax with the exact timestamp

Before

$from = $request->from;
$to = $request->to;
Reservation::whereBetween('reservation_from', [$from, $to])->get();

After

$from = date('Y-m-d', strtotime($request->from));
$to = date('Y-m-d', strtotime($request->to));
Reservation::whereBetween('reservation_from', [$from, $to])->get();

Note: if you stored date in string form, then make sure to pass the exact format in from and to. Which will be matched with DB.

1

Here's my answer is working thank you Artisan Bay i read your comment to use wheredate()

It Worked

public function filterwallet($id,$start_date,$end_date){

$fetch = DB::table('tbl_wallet_transactions')
->whereDate('date_transaction', '>=', $start_date)                                 
->whereDate('date_transaction', '<=', $end_date)                                 
->get();
1

the trick is to change it :

Reservation::whereBetween('reservation_from', [$from, $to])->get();

to

Reservation::whereBetween('reservation_from', ["$from", "$to"])->get();

because the date must be in string type in mysql

1

@masoud , in Laravel, you have to request the field value from form.So,

    Reservation::whereBetween('reservation_from',[$request->from,$request->to])->get();

And in livewire, a slight change-

    Reservation::whereBetween('reservation_from',[$this->from,$this->to])->get();
1

you can use DB::raw('') to make the column as date MySQL with using whereBetween function as :

    Reservation::whereBetween(DB::raw('DATE(`reservation_from`)'),
    [$request->from,$request->to])->get();
1

Another way:

use Illuminate\Support\Facades\DB;

$trans_from = date('2022-10-08');
$trans_to = date('2022-10-12');
$filter_transactions =  DB::table('table_name_here')->whereBetween('created_at', [$trans_from, $trans_to])->get();

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.