Time format of database field, help needed - laravel

Time is stored in my database as H:i:s format for a timefield.
When I query I want time returned as hours:minutes without the seconds part.
I tried to set the "protected $dateFormat " setting using a Mutator. Can anyone show an example of the dateFormat setting needed? The database must remain hour:minute:seconds time settings, only the retrieved value needs to be changed for display.
protected $dateFormat = 'Y-m-d H:i:s'; // ?

One way to solve it is to treat dates as Carbon instances. The format to save on database will be auto-converted and you should use in any format.
protected $dates = [
'field_name'
];
https://laravel.com/docs/5.8/eloquent-mutators#date-mutators

// converting db column name time_match into the function as getTimeMatchAttribute worked for me.
public function getTimeMatchAttribute($value){
return date('H:i',strtotime($value));
}

you can make it with getters function in your model
like this:
public function getTimeAttribute($time){
return date('h:i',strtotime($time))
}
Time in function name should be your column name in upper case

Related

Laravel 8: issues with dateTime (DataTables & Charts)

This issue is happening across the entire application...
I have datatables & charts:
Datatables don't sort by dateTime correctly, aka Started Column.
Charts always starts with the latest date...not by order:
I am using Carbon for datatables like this:
->editColumn('startDateTime', function ($report) {
return Carbon::parse($report->startDateTime)->format('d M, Y');
})
For the charts, returning data as json then format the date:
$data = TrafficViolation::select('id', 'violationDateTime')
->orderBy('violationDateTime')
->get()
->groupBy(function($data) {
return Carbon::parse($data['violationDateTime'])->format('M');
});
The column type of these dates are DateTime in the database.
What's frustrating is that there is a datatable called Audit Log that came with the theme (Metronic 8) and it's sorting the date correctly here (created at):
And looking to its controller:
->editColumn('created_at', function (Activity $model) {
return $model->created_at->format('d M, Y H:i:s');
})
Looking at the Model there isn't anything related to Carbon or date functions there, noting that the data type of created_at is timestamp.
I tried:
Changing data type to timestamp instead of datetime.
Copying the same code of audit log, no need for Carbon, I get an error format() unknown.
To me it looks like you are overcomplicating things, why don't you just sortByDesc if you need the newest results first I do not understand. You can do this like so:
First in you TrafficValidation model add a casts to datetime
protected $casts = [
'violationDateTime' => 'datetime',
];
Then where you return the query just do
$data = TrafficViolation::select('id', 'violationDateTime')
->orderByDesc('violationDateTime')
->get()
->groupBy(function($data) {
return Carbon::parse($data->violationDateTime)->format('M');
});
And the reason audit log works for sorting is because it by default doesnt look at all at your query sorting, it takes the data and sorts it by itself

Wrong date fetch with eloquentt from MongoDB

I get wrong date from MongoDB using Eloquent in Laravel. My record in database looks like this
"created_at" : ISODate("2020-11-17T15:30:42.131+01:00")
Code to get records from MongoDB
$taskObj = TaskComments::where('task_id', $task_id)->get()->toArray();
Result date for created_at is
1970-01-25 20:31:23 which is wrong, I would like to get in this format 2020-11-17 15:30:42
I would like to create correct Mutator or to define a default date format in Laravel or in MongoDb I am not sure.
Any help is appreciated.
This is fixed my problem, I used a mutator in Model of TaskComments
public $timestamps = FALSE;
public function getCreatedAtAttribute($created_at){
return $created_at->toDateTime()->format('Y-m-d H:i:s');
}

Laravel Date Mutator Requires Parsing?

By default, Eloquent will convert the created_at and updated_at columns to instances of Carbon. When retrieving attributes that are listed in the $dates property, they will automatically be cast to Carbon instances, allowing you to use any of Carbon's methods on your attributes.
I have the following in dates property - i've not included the created_at and updated_at columns as these are converted by default as per above:
protected $dates = ['deleted_at'];
Then I have the following accessor on the model:
public function getCreatedAtAttribute($datetime)
{
return $datetime->timezone('Europe/London');
}
However the above throws the following error:
Call to a member function timezone() on string
If I change the method to the following it works:
public function getCreatedAtAttribute($datetime)
{
return Carbon::parse($datetime)->timezone('Europe/London');
}
The question is why do I need to parse it since it's suppose cast it to a carbon instance when it's retrieved according to docs https://laravel.com/docs/6.x/eloquent-mutators#date-mutators ?
That completely depends on what $datetime is and how you're passing it this this function. It's clearly a string, and not a Carbon instance, but you didn't include the definition for $datetime in you question, so I can only speculate.
That being said, I haven't see mutators that use an external variable, as they are generally designed to access properties of the class you're applying them to, via $this:
public function getCreatedAtAttribute(){
return $this->created_at->timezone('Europe/London');
}
The only caveat I could see with this is naming conflict when trying to use $model->created_at. It should handle it, but something like getCreatedAtTzAttribute(), accesses via $model->created_at_tz might be necessary if you come across issues.
If you check the source code (here), you'll see that accessors have priority over date casts.
If Eloquent finds an accessor for your date attribute (getCreatedAtAttribute), date casting will be ignored. So you'll need to cast it manually within your accessor.

Laravel 5 how to modify default Date accessors?

I have a code like this:
public function getUpdatedAtAttribute($value) {
setlocale(LC_TIME, config('app.locale'));
return Carbon::parse($value)->formatLocalized(__('DateFormat'));
}
I want to run this accessor for each field specified in $dates array instead of manually specifying it for each date field in each model, just like default Carbon instance convertion works. How could I do this? And is there better ways of specifying default locale-dependant date format for Carbon?
I think you can use $dateFormat variable of a model to apply a common date format on all the model fields:
class Flight extends Model
{
/**
* The storage format of the model's date columns.
*
* #var string
*/
protected $dateFormat = 'U';
}
More info: https://laravel.com/docs/5.4/eloquent-mutators#date-mutators
Found an elegant and simple solution: LocalizedCarbon package. It works as simply as this:
use \Laravelrus\LocalizedCarbon\Traits\LocalizedEloquentTrait;
UPD: It seems that this package actually translating only DateDiff's, but anyway I can see how it works and use that logic in my models.
UPD2: I've dig deeper and found out what there is overloaded formatLocalized method, which allows useage of non-standard "%f" parameter, which represents month name in current application locale. So I ended up with one-liner date formatting into my View instead of Model, which is more correct.

Convert timestamp to date in Laravel?

How can I return from the database all rows with a timestamp converted to a date (d-m-Y H:i), using the all() method?
It's not created_at or updated_at column, it's custom attribute, call it birthday if you wish.
timestamp columns like created_at are being parsed first. the U is simply the timestamp format. you can return your own format. for other formats see date docs.
edit: as stated in my comment, getDateFormat() is for both ways (insert, selects). your best bet would be using format inside the model. example:
public function getMyBirthdayAttribute()
{
return $this->my_birthday->format('d.m.Y');
}
use $model->my_birthday to call the attribute.
// controller
$posts = Post::all();
// within sometemplate.blade.php
#foreach($posts as $post)
my formatted date: {{ $post->my_birthday }}
#endforeach
The better way to manage dates with Laravel IMHO is to use the getDates accessor that is build into Laravel.
All you need to do is to set a method on your Model as such.
public function getDates()
{
return [
'my_birthday',
'created_at',
'updated_at',
];
}
This will return a Carbon object. Carbon is insanely awesome for manipulating dates.
It is what Laravel does by default to created_at and updated_at.
You can then do things like:
$my_birthday->diffForHumans() // 2 Days ago
$my_birthday->format('d.m.Y') // 20.02.1979
There are tons of helpers here for you. Check out the Carbon docs: https://github.com/briannesbitt/Carbon
Definitely worth learning. It might not be easy to understand for a beginner. However, I would advise you take a look and get your head around it. It will change your life - Dates can be a pain!
In this case, you need to convert the date within the query, if mysql is being used as your database then you may use a raw query like this:
// Assumed my_birthday is like 1255033470
$raw = DB::raw("date_format(from_unixtime(my_birthday),'%b %d, %Y %l:%i %p') as dob");
$result = Model::get(array('id', 'username', $raw));
You may write it within single line:
$result = Model::get(array('id', 'username', DB::raw("...")));
Just place this on your code
$post it depend on what you create
$post ->created_at->format('d.m.Y')

Resources