Laravel between dates - laravel

I want to check the validity of promo code by comparing date in eloquent but dont know why its not working
$promoCode = self::where('code', $code)
->where('start_date', '>=', Carbon::now()->toDateString())
->where('end_date', '<=', Carbon::now()->toDateString())
->first();
If i comment out 2nd and 3rd line then it works fine. MySQL column type is date. I also tried whereDate method and thats not working too

It looks like you inverted the signs. You are looking for something that is older than start_date and younger than end_date.

Shouldn't the start_date be before now. If so now should be between. Try:
$promoCode = self::where('code', $code)
->where('start_date', '<=', Carbon::now()->toDateString())
->where('end_date', '<=', Carbon::now()->toDateString())
->first();

Related

Apply conditions using closure on Laravel Model collection

I am using Laravel Model collection and want to filter the records
in the first statement, I am checking that I only check the ends when it's has some date otherwise doesn't compare the value.
How to check the null value in this collection?
2nd if is working properly. I also used the filter method but it's not working for me. Can anyone suggest to me how to do this in a proper laravel way? I know I can do this using for each loop but I want to make the query faster. Please suggest your answers. Thank you
$subscriptionsCount = Subscription::where( function($query) {
if($query->where('ends_at', '!=' , null)){
$query->where('ends_at', '>=', now());
}
else if($query->where('subscription_ends_at', '>=', now())){
$query->where('subscription_ends_at', '>=', now());
}
})->where('name', $betTypeName)->count();
Can you try this code as I understood from your question you need whereNotNull
$subscriptionsCount = Subscription::where(function ($query) {
$query->where(function ($query) {
$query->whereNotNull('ends_at')->where('ends_at', '>=', now());
})->orWhere(function ($query) {
$query->whereNotNull('subscription_ends_at')
->where('subscription_ends_at', '>=', now());
});
})->where('name', $betTypeName)->count();
You can try with below whereRaw condition :
$subscriptionsCount = Subscription::where( function($query) {
$query->whereRaw("(CASE WHEN ends_at is not null THEN ends_at = now() WHEN subscription_ends_at >= now() THEN subscription_ends_at >= now() END)" );
})->where('name', $betTypeName)->count();
Hope Above code will be help you. Code is not tested but logic will help you. :)

Laravel eloquent query convert created_at datetime to date

i am querying the database the get my tracker results:
$trackers = TrackerResult::all()
->where('tracker_id', $id)
->where('created_at', '>=', Carbon::now()->subDays(30));
return $trackers;
But this returns me "created_at" field as datetime as its by default. Is there are way to get just the date instead? ('Y-m-d') format.
If you want to compare date only try ->whereDate():
TrackerResult::all()
->where('tracker_id', $id)
->whereDate('created_at', '>=', Carbon::now()->subDays(30));
You could also manually format it using ->format():
TrackerResult::all()
->where('tracker_id', $id)
->where('created_at', '>=', Carbon::now()->subDays(30)->format('Y-m-d'));
you should use DATE function:
$trackers = TrackerResult::all()
->where('tracker_id', $id)
->whereDate('created_at', '>=', Carbon::now()->subDays(30))
->select('column1',column2',DB::raw('Date(created_at) as formattedCreateAt'))
->get();
return $trackers;

Laravel Eloquent whereTime() shows null

I have this query to get the events after the the current time and it shows as null. I think the whereTime condition is not working or I have a typo.
$query = Model::where('id', $request->id)
->where('status_id', 1)
->whereTime('event_date', '>=', Carbon::now())
->first();
When I don't have the whereTime condition and check the results, it shows this result
$query = Model::where('id', $request->id)
->where('status_id', 1)
// ->whereTime('event_date', '>=', Carbon::now())
->first();
dd(Carbon::now()->format('Y-m-d H:i:s'), $query->event_date);
Result
"2020-04-15 20:07:43"
"2020-05-23 18:00:00"
If your date like this "2021-03-21 13:33:52" then separate date and time like below
$date = Carbon::parse($timestamp)->format('Y-m-d');
$time = Carbon::parse($timestamp)->toTimeString();
Now you got date and time separated and write query to desire model like below:
User::where('status', 1)->whereDate('created_at', '>=', $date)
->whereTime('created_at', '>', $time)->get();
Hope this will help you. This works for me

Laravel collection with multiple date filter with or operator

I'm trying to filter several items from a Collection in Laravel 5.7. The items have a startdate and an (optional) enddate.
The filter i'm trying to create is the following.
startdate <= now() AND
( enddate >= now() OR enddate = '' OR enddate = NULL )
I've tried the following but it doesn't work:
$this->items->where([
['startdate', '<=', date('Y-m-d'))],
['enddate', '>=', date('Y-m-d')]
])->orWhere([
['startdate', '<=', date('Y-m-d'))],
['enddate', '=', '']
])->orWhere([
['startdate', '<=', date('Y-m-d'))],
['enddate', '=', null]
]);
More cleaner way would be using closure like this:
$this->items->where('startdate', '<=', date('Y-m-d'))
->where(function($q) {
$q->where('enddate', '>=', date('Y-m-d'))
->orWhere('enddate', '')
->orWhereNull('enddate');
});
And probably as suggested in comment you should in fact use items() instead of items because using items you probably get elements from database instead of adding constraints to database query before.
Thanks to Marcin Nabialek i've got the solution.
I've had to use $this->items() instead of $this->items and had to append it with the ->get() function.
The result:
$this->items()->where('startdate', '<=', date('Y-m-d'))
->where(function($q) {
$q->where('enddate', '>=', date('Y-m-d'))
->orWhere('enddate', '')
->orWhereNull('enddate');
})->get();

Making a query to get elements active on a time between 2 specific dates

Cant seem to get the logic right. I have a function that takes 2 dates ($date1 and $date2). I have database records of events that also have 2 dates (starting_at and ending_at).
I want to get all events that completely or partially overlap with time between $date1 and $date2. I have browsed other similar topics and came up with this... but i have a feeling it is not correct.
$events = Event::with(['user']);
$events->where(function($query) use ($date1,$date2) {
$query->where(function($query) use ($date2) {
$query->where('starting_at', '<=', $date2);
});
$query->where(function($query) use ($date1) {
$query->where('ending_at', '>=', $date1);
});
});
If dates are in the same table, use:
$events = Event::with('user')
->where('starting_at', '<=', $date2)
->where('ending_at', '>=', $date1)
->get();
Make sure you've added starting_at and ending_at to the dates array:
protected $dates = ['starting_at', 'ending_at'];
With Laravel 5.3 (maybe 5.2, but 5.3 for sure) you can do:
$events = $events->whereBetween($date1, $date2)->get();
Lower version could be:
$events = $events->where('starting_at', '<=', $date2)
->where('ending_at', '>=', $date1)
->get();
Laravel has a simple way of doing this.
$events = Event::with(['user'])->whereBetween('field_name', array($date1, $date2))->get();
Check the docs here https://laravel.com/docs/5.3/queries#where-clauses
UPDATE
If date1 and date2 are from entirely different columns on the database, then refer #Alexey Mezenin answer which is more appropriate.

Resources