Laravel Eloquent compare dates by specific format - laravel

I am having a little trouble comparing dates in Laravel, where the date is a specific format.
The field in the database has the date like this d-m-Y(20-04-2018) and I am trying to get a result where this date is greater than the date now using this.
$check= Usersubstitutions::where([
['user_id', '=', $request->user],
['date_to', '>=', date("d-m-Y")]
])->first();
And it never works. I var dumped to see what compares, using a foreach and it says that 20-05-2018 is NOT greater than 04-04-2018.

Convert your column to a date format, such as DATE, and then it will work as intended.

Since your field is a varchar try to cast it first to DATE then compare it with date('d-m-Y') like :
$check= Usersubstitutions::where('user_id', $request->user)
->where(DB::raw("DATE(date_to) >= '".date('d-m-Y')."'"))
->first();
NOTE : It will be better to convert the field type in your database to 'DATE'.

On Laravel 4+ you may use
->whereDate('date_to', '>=', date("d-m-Y")
For more examples, see first message of #3946 and this Laravel Daily article.
but you may also use the ->where() as its more convenient.
Try this:
$dayAfter = (new date()->modify('+1 day')->format('d-m-Y');
->where('date_to', '>=', $dayAfter)
Hope it helps. if not view this qn for further explanations

You seem to be storing a DATE in a varchar field. That's not a good idea. You need to either re-create the table and store date_to as a date using the standard SQL DATE format (and use the format Y-m-d when inserting) or cast the column to a date when selecting:
$check= Usersubstitutions::where([
['user_id', '=', $request->user],
[\DB::raw("STR_TO_DATE(date_to,'%d-%m-%Y')") ', '>=', date("Y-m-d")]
])->first();
Note this will make any indexes useless and will make the query run very very (very) slowly.
Note: STR_TO_TIME is MySQL only but there are equivalents in other DBMSs e.g. in SQL Server it seems to be CONVERT(DATE, date_to, 105)

Related

Laravel eloquent compare datetime with query builder

I'd like to compare datetime values (with date AND time). First I tried this, but it does not work, as it only compares the date, not the time:
$events = $events->whereDate('end', '>=', $input['after']);
I thought that a simple where would help, but it does not:
$events = $events->where('end', '>=', $input['after']);
The reason for that is, that my input value is 2022-10-10T00:00:00 and the database read gives 2022-10-10 00:00:00 (the T in the middle was added in the input).
I'd like to stick to the isoformat (using the T), however inside the database that format gets casted to a value without T it seems. The reason for that might be the cast in the model: 'end' => 'datetime',
What would be the best way to solve this issue and compare datetime objects (and how)?
Change the model cast
Cast the input
What would be the best way to solve this issue and compare datetime objects
The best way is still to convert the input with the data type format of the date and time column
You can use : $dateConvert = date('Y-m-d H:i:s', strtotime($input['after']));
But I suggest you use carbon library :
$dateConvert = \Carbon\Carbon::parse($input['after'])->format('Y-m-d H:i:s');
And :
$events = $events->where('end', '>=', $dateConvert );

Having a problem with Laravel Eloquent in query date format transformation

I am using laravel to make a query and return all results that match several criteria. One of them is by date, the problem is that I
store dates in the database in this format:
2021-03-26 12:20:00
and display them in this format:
March 26, 2021
It is a requirement for the project that if you search: March 26
All items with that given month and day are returned
This needs to be done in the query itself, because I also use pagination and other search and orderBy criteria
I am using this:
{...}
$attrDate = 'appointment.date';
$query->orWhereDate($attrDate, 'LIKE', ["%{$search}%"]);
$query->orderBy('appointment.date', $order)->take($pagination)->skip($skip);
$appointments=$query->get();
{...}
That works if I search for numbers cointained in the appointment dates (26, 2021...)
But I also want to be able to search by month in string format, like 'March 26' or 'March 26, 2021' and show appointments for that given date. There is where I get the errors when I try this:
$attrDate = 'appointment.date';
$date_transform= "DATE_FORMAT({$attrDate}, '%F%j,%Y')";
$query->orWhereDate($date_transform, 'LIKE', ["%{$search}%"]);
It returns a code 500 response with an sql error.
I don't know what to do, since all of this are requirements for the project and I can't really change them. I have searched in the Laravel documentation, but I have not found anything that can help me solve this. Thanks in advance.
Laravel have also eloquent methods whereDate / whereMonth / whereDay / whereYear / whereTime, so you can use any of them.
$users = DB::table('users')
->whereMonth('created_at', '12')
->get();
Source: Laravel Docs
I would personally recommend using carbon's parser like e.g.
$attrDate = 'appointment.date';
$dateSearch = Carbon::parse($search);
$query->orWhereDate($attrDate, $dateSearch);
$query->orderBy('appointment.date', $order)->take($pagination)->skip($skip);
$appointments=$query->get();
This offloads the issue to Carbon's date parsing (which is pretty good). The issue here is it will assume the year rather than searching for any year

Query using eloquent whereMonth where date is string

In one of the tables a column with type of varchar contains a date with the following format day-month-year. I would like to run a query using eloquent on that table with whereYear and whereMonth, but I get an error since the column booking_date is not of type Date.
The query I am trying to run is
MyTable::whereYear('booking_date', '=', $year)
->whereMonth('booking_date', '=', $month)
->get();
And getting the following error
"SQLSTATE[42883]: Undefined function: 7 ERROR: function pg_catalog.date_part(unknown, character varying) does not exist\nLINE 1: ...\" = $1 and \"said_table\".\"deleted_at\" is null) and extract(ye...\n ^\nHINT: No function matches the given name and argument types. You might need to add explicit type casts.
Is there a way to cast the string value to a date before querying it, maybe with using raw expressions? If yes, any hints would be great.
If this field is going to be a date on the particular model all the time (and with a name like 'booking_date', it might well be), it is even easier than having to deal with it on every query. You can cast it within the dates field on the model itself:
protected $dates = [
'booking_date',
];
By default, Eloquent will convert the created_at and updated_at columns to instances of Carbon, and the above will do the same for booking_date. No further casting required. From Laravel docs on date mutators
You may easily achieve that thanks to Carbon library which is included within Laravel:
use Carbon\Carbon;
$targetDate = Carbon::now()->year($year)->month($month);
MyTable::whereYear('booking_date', '=', $targetDate)
->whereMonth('booking_date', '=', $targetDate)
->get();

Laravel compare timestamps in where statement

I have a block of code in which I am passing a Carbon date that looks like this:
2017-08-18 22:53:50.031922
And want to compare it to created_at time stamps of some records. However, it seems that the records are not being filtered out; is the comparison in the where statement valid?
$test = Auth::user()->tests()->with([
'participants.testRecords' => function ($query) use ($latestCapture) {
$query->select('id', 'score', 'test_id', 'participant_id', 'capture_timestamp', 'score', 'created_at');
$query->where('test_records.created_at', '>', $latestCapture);
}])->findOrFail($id)->toArray();
If $latestCapture is instancej Carbon, you should rather use here:
$latestCapture->toDateTimeString()
to make sure you pass valid date string.
There is also one more thing - you should make sure created_at is filled in PHP and not in MySQL (this is default in Laravel) - if it's not you can expect time shifts when you have different time zones in PHP and MySQL

Laravel/Eloquent and comparing dates

I want to return all of the rows in my database table that are a day or less old. I'm using Laravel 4. This is what I tried:
$date = date('Y-m-d H:i:s');
return MainContact::where(DATEDIFF('timestamp', $date), '<=', 1)->get();
This doesn't work. I read the documentation and it doesn't seem like you can pass Laravel MySQL functions. timestamp is a datetime field. How can I compare these dates in Laravel 4?
The answer that user1977808 gave you is not good because MySQL can't use an index on the timestamp column, since it has to compute an output of the DATE_SUB function for every row. Avoid such queries, they have to process the entire table every time!
How about something like this:
return MainContact::where('timestamp', '>=', time() - (24*60*60))->get();
I put the >= in there because you said "a day or less old", so they must have timestamp that is later than yesterday.
Alternatively,
You can use Carbon API that bundle with Laravel.
ModelName::where( 'timestamp', '>=', Carbon::now() )->get();
Reference: http://laravel.com/docs/5.1/eloquent-mutators
You could also use whereDate(), whereDay(), whereMonth() and whereYear(). In this case, whereDate() could be used as such, with Carbon's easy date functions:
return MainContact::whereDate('dateField', '<', Carbon::now()->subDay())->get();
return MainContact::where('timestamp', '>=', time() - (24*60*60))->get();
You can also do a raw query by using:
$results = DB::query( 'query' );
You only don't the the model object back in the results var

Resources