Validate Date and Time in the Laravel Model - php

I have a datepicker plugin to pop-up a calendar view to allow users to select a date + time, however the format which it produces is:
May 9, 2016 8:30 AM
When storing to the database, I need the format to be:
2016-09-05 08:30:00
In the controller of my application, I have:
public function save(Request $request)
{
Entry::create($request->all());
return redirect('entries');
}
Which saves the users form input, however it doesn't save the datetime due to the incorrect format. I have tried creating a new function to format the date before entering it into the database.
public function formatDate($data)
{
$returnDate = DateTime::createFromFormat('Y-d-m G:i:s', $data);
return $returnDate->format('Y-d-m G:i:s');
}
However when I call the function from the save function, it says undefined function. Am I doing something wrong or what would be the correct way to achieve this?

You have to set the correct format for DateTime::createFromFormat(). Create from format means, you have to tell a pattern to match any information in the given date. For your date, the pattern is:
DateTime::createFromFormat('F j, Y g:i A', $data);
Here is a demo: https://eval.in/567629
A list of all format options: http://php.net/manual/en/function.date.php

Both functions are inside the model?
If so, how are you trying to call the formatDate function?
You could use an anonymous function instead, try:
$formatted_date = function() use ($data) {
$returnDate = DateTime::createFromFormat('Y-d-m G:i:s', $data);
return $returnDate->format('Y-d-m G:i:s');
};
Inside your controller or model.

In Laravel, the created_at and updated_at are casted to Carbon objects
https://laravel.com/docs/5.2/eloquent-mutators#date-mutators
With your date, you could do the same thing
class User extends Model
{
/**
* The attributes that should be mutated to dates.
*
* #var array
*/
protected $dates = ['created_at', 'updated_at', 'your_date'];
}
then, when saving the date, it will be cast to the correct format.
Give that a try and let us know how you get on!

For example;
$data = "May 9, 2016 8:30 AM";
return date('Y-d-m H:i:s',strtotime($data));

Related

Change automatically the format of date fields (Laravel)

I'm looking for a DateTime Mutator that change the format of dates, I'm working with Oracle DB and the admitted Format is (DD/MM/YYYY) and the input type "date" stores dates in (YYYY,MM,DD) format.
I found the $date function and a trait by Torzer, but I have to indicate the fields that I want to convert the format.
is there some trait or function that detect all date fields and convert them automatically in a format (DD/MM/YYYY)? this without indicate the field.
nowadays I use protected $date in my model:
protected $dates = [ 'fecha_nac', 'fecha_nac1', 'fecha_nac2', ];
By default laravel uses date formate 'Y-m-d H:i:s' if you want to use a different format you can customize it in your model in the following way.
protected $dateFormat = 'your date formate';
in your case it will be.
protected $dateFormat = 'd-m-Y';
You can override the getDates method on HasAttributes trait.
/**
* Get the attributes that should be converted to dates.
*
* #return array
*/
public function getDates()
{
$defaults = [static::CREATED_AT, static::UPDATED_AT];
return $this->usesTimestamps()
? array_unique(array_merge($this->dates, $defaults))
: $this->dates;
}
On your model:
public function getDates()
{
$dates = parent::getDates();
// add your dynamic logic here
return $dates;
}
I would really go for explicitly defining which fields should be converted as these dynamic operations can be expensive if you are working with the model quite a lot.

Different date accessors in same Model

I have this, and it works nicely to give me UK-formatted dates:
protected $dateFormat = 'd-m-Y';
protected $dates = ['purchased', 'warranty_expires', 'scrapped_on', 'location_date', 'user_date'];
However, I also have created and modified (not the standard Laravel ones, but my own) that are Timestamps, not dates. How can I automate the formatting of those two fields when they are retrieved, to something like 'd-m-Y H:i:s' ?
You can do this with Carbon library
public function getFormattedPurchasedAttribute($date)
{
return Carbon::createFromFormat('Y-m-d H:i:s', $date)->format('d-m-Y H:i:s');
}
You have to use carbon class. Write this line in the top where all namespace are used.
use Carbon;
I personally don't use $dateFormat attribute because it changes format for all dates fields. What I would do is creating custom accessors to get formatted fields for example:
public function getFormattedPurchasedAttribute($value) {
return $this->asDateTime($value)->format('d-m-Y H:i:s');
}
so you can now use $model-formatted_purchased to get purchased field formatted in way you want

Laravel mutate date before saving to database?

I have a date that's being selected in a datepicker in the following format
Y-m-d g:i A
So using AM/PM, it shows the following in my input field, which is correct
When I submit the form offcourse Laravel won't update the record because the format is unknown to my DATETIME field in mysql.
My 'date' field is added to the $dates array so it should be parsed by Laravel
I tried using a Mutator on my Model as following, without success
public function setDateAttribute($value)
{
$this->attributes['date'] = Carbon::createFromFormat('Y-m-d g:i A', $value)->format('Y-m-d H:i:s');
}
The original value is not being updated.
Any idea what I might be doing wrong?
Thank you
Take a look at Laravel's date mutators, this handles the accessing and mutating dates going into and out of the database for you much like it does with created_at and the other default dates.
Basically, you need to add the date field to the $dates array on your model like so:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be mutated to dates.
*
* #var array
*/
protected $dates = [
'created_at', // Add if you're using timestamps on the model
'updated_at', // Add if you're using timestamps on the model
'deleted_at', // Add if you're using softDeletes on the model
'date'
];
}
This way when the model is persisted to the database it's done so as a DATETIME, whereas when it is being read from the database into your model it will be a Carbon instance
It seems that your carbon function is ok. But why it does not work, don't understand. But I have solution using PHP date function.
public function setDateAttribute($value)
{
$this->attributes['date'] = date("Y-m-d H:i:s", strtotime($value);
}
Laravel's date mutator expects a format like 'Y-m-d H:i:s', but you can use the $dateFormat attribute on your model to specify a different format. E.g.:
protected $dateFormat = 'Y-m-d g:i A';
Check out the Date Formats section in the docs under Date Mutators
Alternatively, you can parse the date using Carbon outside of the model, because attributes listed in the $dates will also accept Carbon instances:
$model->date = Carbon::createFromFormat('Y-m-d g:i A', '2016-11-29 02:00 PM');
This is the approach I typically use. To me this feels more like a front-end concern where you're trying to map a user-friendly format to one your models/DB expects, so I'll usually put this logic into a controller.

laravel 5 format datetime

I have an array that return the following date time:
$item['created_at'] => "2015-10-28 19:18:44"
And I need this outuput:
"2016-08-10T13:15:00.000+10:00"
Exist any function to convert this date?
Try this:
$dt = new \DateTime('2015-10-28 19:18:44', new \DateTimeZone('Europe/London'));
dd($dt->format('c')); // string '2015-10-28T19:18:44+00:00' (length=25)
Alternatively take a look at Carbon
You can use Laravel's accessors to get "reformatted" created_at.
public function getCreatedAtAttribute($value)
{
//Since Laravel uses Carbon you can do.
return $value->format('c');
}
This way anytime you do something like $model->created_at it will return modified created_at.
If you want to change datetime format for created_at in your database as well, you can use mutators.
More information you can find on the Laravel's docs page.

Convert String to Carbon

I am using Laravel 5.1
Few days ago I used protected $dates = ['license_expire'] in my model to convert the string date to Carbon instances. In HTML the default value in create form for the date was Carbon\Carbon::now()->format('Y-m-d')
In order to show alert in home page i used <p>Licence Expired: <b>{{ $employee->license_expire < Carbon\Carbon::now()?'License has expired':$employee->license_expire->diffForHumans() }}</b></p>
Till then diffForHumans() method works fine.
But in that case the edit form's default value also was today's date no matter what was in database(I am using a partial form). To resolve it I change the default value in HTML was NUll. And add another method in my model to show current date in create form.
public function getLicenseExpireAttribute($date)
{
return Carbon::parse($date)->format('Y-m-d');
}
After that when i go to home page i have an FatalErrorException which says Call to a member function diffForHumans() on string
When I check the date with dd($employee->license_expire) it become STRING again.
Can anybody tell me how can I convert the string to Carbon in this situation?
or
Make my create form's default date as today's date, the edit form's date from database and I can use diffForHumans() to show alert in home page?
You were almost there.
Remove protected $dates = ['license_expire']
and then change your LicenseExpire accessor to:
public function getLicenseExpireAttribute($date)
{
return Carbon::parse($date);
}
This way it will return a Carbon instance no matter what.
So for your form you would just have $employee->license_expire->format('Y-m-d') (or whatever format is required) and diffForHumans() should work on your home page as well.
If you're using Laravel 9+, you can alternatively use the updated syntax for defining Accessors :
use Illuminate\Database\Eloquent\Casts\Attribute;
public function licenseExpire(): Attribute
{
return Attribute::make(
get: fn ($value) => Carbon::parse($value);
);
}
Why not try using the following:
$dateTimeString = $aDateString." ".$aTimeString;
$dueDateTime = Carbon::createFromFormat('Y-m-d H:i:s', $dateTimeString, 'Europe/London');
$filter['dateOfService']='06.2021';
$d1 = Carbon::createFromFormat('m.Y', $filter['dateOfService'], 'Europe/Warsaw')->format('m.Y');
Try this
$date = Carbon::parse(date_format($youttimestring,'d/m/Y H:i:s'));
echo $date;

Categories