Laravel Date comparison not working in Eloquent query - laravel

I do not understand why but following query return null resultset.
due_date is Carbon date and $now=Carbon:today();
$subQuery = BillTable::where('busi_id', $business->busi_id)
->where('due_date','>=',$now)
->where('due_date','<',$now->addMonth())
->get();
Also when I use whereBetween it doesn't work.
$subQuery = BillTable::where('busi_id', $business->busi_id)
->whereBetween('due_date',[$now, $now->addMonth()])
->get();
But when I just to greater than or lesser than it works
$subQuery = BillTable::where('busi_id', $business->busi_id)
->where('due_date','>',$now->addWeek())
->get();
What am I missing here?

The problem here is that you are using the same instance for both range limits. When you call addMonth you add the month to the instance stored in $now. The two examples below illustrate the issue:
1. Using and modifying the same variable in two separate statements works as you'd expect:
$now = Carbon::now();
dump($now); // prints 2015-12-12 14:50:00.000000
dump($now->addMonth); // prints 2016-01-12 14:50:00.000000
2. Using the same variable and modifying it in the same statement that passes the values to a method, will work differently, because it will be evaluated before being passed to the method. Meaning that both parameters will be equal because they both contain the same instance from the $now variable, which after getting evaluated will contain the DateTime of one month from now.
$now = Carbon::now();
// Calling `addMonth` will change the value stored in `$now`
dump($now, $now->addMonth());
// The above statement prints two identical DateTime values a month from now:
// 2016-01-12 14:50:00.000000 and 2016-01-12 14:50:00.000000
This means that your current code was checking if the entries were due only exactly one month from now.
To fix it you need to use two instances in two separate variables:
$from = Carbon::now();
$to = Carbon::now()->addMonth();
$subQuery = BillTable::where('busi_id', $business->busi_id)
->whereBetween('due_date',[$from, $to])
->get();

It looks like it is because I used '$now' in the query.
Like is said before the query I did $now=Carbon::today(); and use $now in the query.
But then I got rid of that and changed the query to use Carbon::today() it worked.
$subQuery = BillTable::where('busi_id', $business->busi_id)
->whereBetween('due_date',[Carbon::today(), Carbon::today()->addMonth())
->get();
It is weird.
Thanks,
K

Related

How to select min and max in laravel

I want to convert this code in laravel.
SELECT MAX(date_start) AS DateStart,MIN(date_end) AS DateEnd FROM DBTest
And I try this code
$data = DB::table('DBTest')
->select(max('date_start'), min('date_end')))
->get();
Return Error: max(): When only one parameter is given, it must be an array
I am using laravel 5.2, and SQLyog as database
I am confuse in syntax please help me
You can't use functions in select statement, but you can use raw SQL :
$data = DB::table('DBTest')
->select(\DB::raw('MIN(date_start) AS DateStart, MAX(date_end) AS DateEnd'));
->get();
You can do it like this:
For the max start date:
max = DB::table('DBTest')->select('date_start')->orderBy('date_start', 'desc')->first();
For min end date:
min = DB::table('DBTest')->select('date_end')->orderBy('date_end', 'asc')->first();
You have to use something called selectRaw method in Laravel in order to achieve this result. Chaining method like ->max('columnA')->min('columnB') will not work. So, here is the solution:
$data = DB::table('DBTest')
->selectRaw('MAX(date_start) AS DateStart, MIN(date_end) AS DateEnd')->get();
Try MIN() and MAX() functions in the sql query.
$data = DB::table('DBTest')
->select(\DB::raw('MIN(date_start) AS startDate, MAX(date_end) AS endDate'));
->get();

How to use search value contain in array field using eloquent in Laravel

I'm working on laravel array serialize. Below is serialize in controller.
public function CreateSave(CreateTestTopicRequest $request){
...code..
$testtopic->class_room_id = $request->classroom;
$testtopic->roomno = serialize($request->roomno);
...code..
}
Then, roomno will be saved to database like.
a:2:{i:0;s:1:"1";i:1;s:1:"2";}
I would like to get result. For example class_room_id = 1 and roomno only contain in roomno array. I may use command to get all as below.
$testtopics = TestTopic::where('class_room_id',1)->get();
But, I do not know to get record only class_room_id = 1 and roomno contain in array. Any advice or guidance on this would be greatly appreciated, Thanks
You can use like search in json fields
TestTopic::where('class_room_id',1)->where('roomno', 'like', '%"id": 1%')->first()
When checking for an array of values the whereIn method can be used:
$roomno = 'a:2:{i:0;s:1:"1";i:1;s:1:"2";}';
$testtopics = TestTopic::where('class_room_id',1)
->whereIn('roomno', unserialize($roomno))
->get();
Multiple where statements can be combined by passing an array:
$roomno = 'a:2:{i:0;s:1:"1";i:1;s:1:"2";}';
$users = TestTopic::where([
['class_room_id', '=', '1'],
['roomno', '=', $roomno],
])->get();

access data from database to compare with current date to calculate total days

I have tried to access date stored in my db table and compare it with current date so that I can get the number of days but it shows this error
DateTime::__construct(): Failed to parse time string ([{"quit_date":null},{"quit_date":null}]) at position 0 ([): Unexpected character
This is the code that use in my controller
$quit_date = Information::select('quit_date')
->where('user_id','=',\Auth::user()->id)
->get();
$date = new Carbon($quit_date);
$now = Carbon::now();
$day = $date->diffInDays($now);
but if I set the $quit_date manually with the date for example "2019-04-25 00:00:00.000000", the code works fine and shows the days different between the dates, but when I use the Information::select to read the date from database, it shows error.
use Auth; //top of controller
$checkdate = Information::
->where('user_id','=',Auth::user()->id)
->first();
$quit_date=$checkdate->quit_date;
$date = new Carbon($quit_date);
$now = Carbon::now();
$day = $date->diffInDays($now);
The issue occurs because you are using ->get() at the end of your query. That method returns a Collection not a single object. The issue is solved by using ->first() to return a single object.
The error itself is because in the line $date = new Carbon($quit_date);, Carbon cannot convert a Collection to a date.
This should work:
$quit_date = Information::select('quit_date')
->where('user_id','=', \Auth::user()->id)
->first(); //Changed this from ->get()
$date = new Carbon($quit_date);
$now = Carbon::now();
$day = $date->diffInDays($now);

Select with advanced where clauses and timestamp using Carbon and DB

I have a code to generate a SQL query from a table.
I want to select items that exist between dates and a true value in another field.
DB use in construction and Carbon facades, following advice on how to work with Carbon in laravel 5.
But I do not get the effect I returns all rows
private function runBids() {
$dt = Carbon::parse(Config::get('constants.start_lot'));
$start = $dt->toDateTimeString(); // 2006-05-08 08:34:59
$end = $dt->addDay()->startOfDay(); // 2006-05-09 00:00:00
$lots = DB::table('lots')
->select('id')
->where('end',false)
->where('end_auction', '<=', $end)
->where('end_auction', '=>', $start) // Not work. Return 0 results
// if comment ->where('end_auction', '=>', $start) result 39 results with date
// between dates
// (start it's date of first element of table order by end_auction)
->get();
$lots_id = array();
foreach ($lots as $value){
$lots_id[] = $value->id;
}
dd($lots_id);
}
It all seems correct, except for the operator used on the $start parameter. You have
->where('end_auction', '=>', $start)
And you should have
->where('end_auction', '>=', $start)
Notice the difference between => and >=. The first throws a MySQL error. You could try to wrap that code around a try ... catch block, and check the exception message.
You can also log the executed queries using one of this answers, to check the executed query whenever you don't get the expected results.

Query builder where between custom date format

My field date (varchar datatype) is in a custom date format it's dd-mm-yyyy.
Example : 01-01-2016
I want to get data between specific dates from a database field date. Let's say input data are stored in variables: startDate & endDate.
I tried with this query but the result are weird.
$query = DB::table('test')->whereBetween('date', array($startDate, $endDate))->get();
I think it fails because I used a custom date format.
How can this be solved?
#updated
let's say i have date like this
29-12-2015
29-12-2015
29-12-2015
30-12-2015
29-12-2015
01-01-2016
06-01-2016
i set $startDate & $endDate like this
$startDate = "01-12-2015";
$endDate = "01-01-2016";
it's even not get any result with this script
$query = DB::table('test')->whereBetween('date', array($startDate, $endDate))->get();
but if I using
$startDate = "01-12-2015";
$endDate = "31-12-2015";
i get all data...which it's wrong result because 2016 data should not in range...it's somehow like not filtered
since your date datatype is varchar you can try to use str_to_date function in mysql then before using $starDate and $endDate variable convert it's format first.
Sample code is like this.
$startDate = date("Y-m-d", strtotime("01-12-2015"));
$endDate = date("Y-m-d", strtotime("31-12-2015"));
$query = DB::table('test')->whereBetween("str_to_date(date, '%d-%m-%Y')", array($startDate, $endDate))->get();
Hope that helps.
The format shouldn't be a problem; Unless the data you POST are in different format from what the database holds. Make sure that the format for the date field in database matches the format to the ones you store in $startDate, $endDate.
Also I would solve this by taking a slightly different approach. This can become a model function, call it getDataBetweenDates(). Each time you need to query the database, to retrieve the data between a specified range of dates, you do a call to this function from the controller:
Model
public function getDataBetweenDates($startDate, $endDate) {
$range = [$startDate, $endDate];
return $this
->whereBetween('date', $range)
->get();
}
Controller
$startDate = Input::get('start_date');
$endDate = Input::get('end_date');
$model = new Model; // use your model name;
$data = $model->getDataBetweenDates($startDate, $endDate);

Resources