Convert timestamp to date in Laravel? - 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')

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

Carbon Date Being Saved as String in Database

I am trying to seed some data using Factories. One of the fields I'm trying to seed is a date field -- and I do so with the following code in my factory:
return [
...
'date' => Carbon::now()->subDays(rand(1, 365))->startOfDay()
];
The problem is, this is getting saved in the database as a string -- which means that I CANNOT do the following in my blade templates: {{ $transaction->date->format('M, d Y') }},
When I try that, I get the following error message: Call to a member function format() on string.
Just as a test, I tried in my blade template the same exact code, just switching out created_at for date - and it works as I want. I.e., this works: {{ $transaction->created_at->format('M, d Y') }}.
In case it matters, the created_at field is created using $table->timestamps() in my migration file whereas the date field is created as follows: $table->date('date');.
Any idea what I need to do in order to get this to work?
Thanks.
Laravel provides a method to "cast" certain Model attributes to specific datatypes, including strings, integers, dates, etc. Since Carbon is built in to Laravel, specifying the date type auto-converts Model attributes to a Carbon instance. All you need to do is provide that logic to your model:
class Transaction extends Model {
protected $casts = [
'date' => 'date'
];
...
}
Now, when you retrieve a Transaction model record, the date attribute will automatically be a Carbon instance:
$transaction = Transaction::first();
dd($transaction->date, get_class($transaction->date));
// ^ Carbon\Carbon #1646769789^ {#4514 ... }, `Carbon\Carbon`
Now, you can perform Carbon logic, simply by chaining:
{{ $transaction->date->format('Y-m-d') }}
// `2022-03-08`
More casting types are available, and you can specify multiple attribute casts by simply adding them as key/value pairs to the $casts array. Full documentation is here:
https://laravel.com/docs/9.x/eloquent-mutators#attribute-casting

Time format of database field, help needed

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

Get specific values from controller function

I started learning Laravel and I am trying to achieve the following:
Get data from database and display specific field.
Here is my code in the controller:
public function show()
{
$students = DB::select('select * from students', [1]);
return $students;
}
Here is my route code:
Route::get('', "StudentController#show");
That all works for me and I get the following displayed:
[{"id":1,"firstname":"StudentFirstName","lastname":"StudentLastName"}]
How can I get only the "lastname" field displayed?
Thanks in advance!
DB::select('select * from students')
is a raw query that returns an array of stdClass objects, meaning you have to loop through the array and access properties:
$students[0]->lastname
You can also use the query builder to return a collection of objects:
$collection = DB::table('students')->get();
$student = $collection->first();
$student->lastname;
Lastly, using the query builder, you can use pluck or value to get just the last name. If you only have one user, you can use value to just get the first value of a field:
DB::table('students')->where('id', 1)->value('lastname');
I strongly advise you to read the Database section of the Laravel docs.
$students[0]['lastname'] will return the last name field, the [0] will get the first student in the array.
I would recommend creating a model for Students, which would make your controller something like this:
$student = Students::first(); // to get first student
$student->lastname; // get last names
If you only want the one column returned, you can use pluck()
public function show()
{
$last_names= DB::table('students')->pluck('lastname');
return $last_names;
}
This will return an array of all the students' lastname values.
If you want just one, you can access it with $last_names[0]
As a side note, your show() method usually takes a parameter to identify which student you want to show. This would most likely be the student's id.
There are several ways you can accomplish this task. Firstly, I advise you to use the model of your table (probably Students, in your case).
Thus, for example,to view this in the controller itself, you can do something like this using dd helper:
$student = Students::find(1);
dd($student->lastname);
or, using pluck method
$students = Students::all()->pluck('lastname');
foreach($students as $lastName) {
echo $lastName;
}
or, using selects
$students = DB::table('students')->select('lastname');
dd($students);
Anyway, what I want to say is that there are several ways of doing this, you just need to clarify if you want to debug the controller, display on the blade...
I hope this helps, regards!

view database data that was created today by a specific user

I'm creating a foodlog and I want a user to be able to search through the days and view food that was only logged that day.
For example, on the page for today's date I only want to see all the food items that I logged for today.
I have my table getting all data from that specific user from all dates, but how do I narrow it down to just today?
FoodlogController.php
public function show() {
$userId = Auth::user()->id;
$posts = Post::where('user_id', $userId)->get();
return view('foodlog', compact('posts'));
}
This is what my table looks like
I'm going to assume you have the default timestamps on, which add created_at and updated_at fields. If that's not the case, and you log time of creation with a different column, just replace the created_at with it.
Laravel comes with a hand package for dealing with dates - Carbon, which can be used by importing it from Carbon\Carbon namespace.
And Laravel's query builder has a method whereDate (scroll to "whereDate"), which can be used exactly for this.
Combining these 2, you could do this:
$posts = Post::where('user_id', $userId)->whereDate('created_at', \Carbon\Carbon::today())->get();
This will get the posts that were created today.
However
I would strongly recommend you create a hasMany relationship (user hasMany posts and inversely a post belongsTo a user), which would enable to use relationships and do something like this:
$posts = $user->posts()->whereDate('created_at', \Carbon\Carbon::today())->get();
And many more things, the Laravel way.

Resources