Laravel timestamp columns saving with wrong date format - sql-server

I recently updated an old laravel 5.7 project to 8.0 and the created_at and updated_at model timestamps get created with the wrong format. Back in the day i used this code in all models that are from a SQL Server database to get it working between my local and production environment.
public function getDateFormat()
{
if (PHP_OS_FAMILY == 'Windows') {
return 'Y-d-m H:i:s.v';
} else {
return 'Y-m-d H:i:s';
}
}
I use windows to develop the application and a Linux server to run it with apache, but after updating the project the timestamps invert the day and month of the date. For example, if i create a model in the date '2022-06-07 13:00:00' the created_at timestamp will be '2022-07-06 13:00:00'.
Of course, changing the getDateFormat() method to only return 'Y-d-m H:i:s.v' in all environments works, but create another problem with php date function, for example, if i call <p> updated at: {{ date('d/m/Y H:i:s', strtotime($model->updated_at)) }}</p> the desired result would be updated at: 07/06/2022 13:00:00 but instead i get updated at: 06/07/2022 13:00:00.
I really dont know if this is a php timezone issue or something related to laravel, since the problem shows at saving/updating rows or displaying formatted data information.

try
date("Y-d-m H:i:s", time());

Please use:
updated at: {{ date('m/d/Y H:i:s', strtotime($model->updated_at)) }}
for the desired result as the above m shows month, d shows days similarly y shows year.

Laravel have Carbon so use it for datetime stuff
use Carbon\Carbon;
...
if(! function_exists('format_date') {
function format_date(string $date): string
{
return Carbon::parse($date)->format('d-m-Y H:i:s');
// something like 31-12-2022 12:00:00, just change format as you need
}
}
From your view:
{{ format_date($model->date) }}
Make sure to check Ref

Related

Laravel AJAX call returns a date of 1 day before

On my Laravel app, I have created an AJAX call to search bookings based on a given name. In the database, every booking contains a date field. For some reason, the date I receive from my controller query is always the day before. So for example, when the date field in the database shows '2021-05-18', the collected date from the query shows '2021-05-17'.
Does anyone have an idea what can be the cause of this and how I can solve it?
I use the same date field in other controller functions and on other views as well, and there the date field is displaying correctly.
Also, in my config > app file I have set the 'timezone' to 'Europe/Brussels'.
A screenshot of my database:
The code in my controller is as follows:
public function searchReservation(Request $request)
{
$users = User::where('name', 'LIKE', '%'.$request->name.'%')
->select('id', 'name')
->get();
foreach($users as $user) {
$user['reservations'] = Booking::where('user_id', $user['id'])->get();
}
return $users;
}
My code in the controller, where I 'transform' the date, before I create a new booking:
if (Carbon::hasFormat($request->date, 'd-m-Y')) {
$request->date = Carbon::createFromFormat("d-m-Y", $request->date);
} else {
$request->date = Carbon::createFromFormat("d-n-Y", $request->date);
}
A screenshot of my database output, where the date is always a day before the real date:
When you are using Carbon for formatting a time, you need to explicitly set the time zone if you intend to process with a time zone other than UTC. Default values like created_at will be automatically saved properly by Laravel respecting the timezone set in config/app.php. For other date/time column you need to explicitly set the timezone for formatting with Carbon. Therefore, your code should be like:
if (Carbon::hasFormat($request->date, 'd-m-Y'))
{ $request->date = Carbon::createFromFormat("d-m-Y", $request->date, config('app.timezone')); //pass timezone value from config as the third parameter
}
else {
$request->date = Carbon::createFromFormat("d-n-Y", $request->date,config('app.timezone'));
}

How format datetime for sql server in laravel?

im trying to format datetime values in laravel to make them match with sql server format, im getting this error:
The separation symbol could not be found Unexpected data found.
Unexpected data found. Trailing data
Im using a custom format in my model:
protected $dateFormat = 'd-m-Y H:i:s';
It works good for the create method con controllers, there is no problem, the error happen when try to update and I think is related to how the value is stored in the database.
Using tinker I retrieve the value of updated_at in my model and is shown in the next format:
updated_at: "2018-07-24 09:14:09.000"
So when Im updating this value the format used is:
protected $dateFormat = 'd-m-Y H:i:s';
I think it should be something like d-m-Y H:i:s.000 but doesnt work, how can I solve this?
I had exactly the same issue, when switching to laravel version 5.6. Now I found the correct way to handle this.
Create a Base class like this and add a public method getDateFormat.
There you return the date a little bit different
return 'Y-d-m H:i:s.v';
See that date (d) and month (m) are switched and at the end you need to put a .v which stands for milliseconds. This worked for me fine. See here my complete Base class:
<?php
namespace App\Models\Base;
use Illuminate\Database\Eloquent\Model;
class BaseModel extends Model
{
public function getDateFormat()
{
return 'Y-d-m H:i:s.v';
}
public $timestamps = false;
}
What version of Laravel are you using? This was fixed in a recent release (can't remember exactly which) that relies on PHP 7.
The dateFormat should be "Y-m-d H:i:s.v". v is Milliseconds (added in PHP 7.0.0). The problem you're experiencing with updates and inserts is caused when the updated/inserted model is returned. It is passed to Carbon to convert date and datetime fields into instances of Carbon, but the datetime fields have 'trailing
You can also try this one in SQL/Select Query:
\DB::raw ("DATE_FORMAT(comments.date,'%d-%m-%Y %H:%i:%s') as sth_date")
E.g:
Comment::orderBy('date','desc')->with('user')
->join('users','comments.id_user', '=', 'users.id')
->select('users.username', 'comments.id', 'comments.id_race', 'comments.status', 'comments.ip_address', 'comments.id_user',
\DB::raw ("DATE_FORMAT(comments.date,'%d-%m-%Y %H:%i:%s') as sth ") );
Time fraction is a configuration of your database, you can see it below, so you can just try to switch on your database.
https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html
But using something like $d->format("Y-m-d H:i:s.u") you can format/manipulate using class Datetime().

Displaying the "created_at" field correctly in vuejs

I am trying to display the "created_at" field from my database using laravel as my backend app and vuejs as my frontend app.
This is what is presently being displayed:
Time: { "created_at": "2018-02-22 14:14:30" }
This is what I want to be displayed:
Time: 22-Feb-2018 14:14:30
My laravel backend code:
$date = loan_request::all('created_at')->toArray();
return([$date]);
Any help rendered would be appreciated..
How I would do the date formating is to use an Eloquent Accessor.
To do this, go to your loan_request model, and simply add the following function.
public function getCreatedAtAttribute($date)
{
return Carbon::parse($date)->format('d-M-Y H:i:s');
}
Be sure to add use Carbon\Carbon; at the top before your class.
Now when you return your date with...
$date = loan_request::all('created_at')->toArray();
return([$date]);
Your dates in the json array will always be in the format 22-Feb-2018 14:14:30
You can read more about Accessors and Mutators in the Laravel Docs here
Edit
I missed when reading the first time you want to remove the created_at key. As others have pointed out you could do that in your vue code by doing one of the following.
<div v-text="date.created_at"></div>
or..
<div>{{data.created_at}}</div>
If you still really want laravel to only return the date without the created_at key then change your query in Laravel to the following.
$date = Location::all('created_at')->pluck('created_at');
return ([$date]);
To answer your question (with your existing HTML):
$date = loan_request::all('created_at')->pluck('created_at')->toArray();
return $date; // will return an array of dates
But what you can do if return the same thing as before but display something like that (and not using my laravel change):
date = { "created_at": "2018-02-22 14:14:30" }
in your html / vue.js file
<span>{{ date.created_at }}</span> <!-- "2018-02-22 14:14:30" -->
Because for now you seem to display something like this:
<span>{{ date }}</span> <!-- { "created_at": "2018-02-22 14:14:30" } -->
And if you want to format the date, you can only do that in the frontend by using filters in vue.js! (You can code your own or use https://github.com/brockpetrie/vue-moment)
<span>{{ date.created_at | moment("dddd, MMMM Do YYYY, h:mm:ss a") }}</span>
<!-- e.g. "Sunday, February 14th 2010, 3:25:50 pm" -->

cakephp timeHelper isToday

I am using cakePHP time format to change a date to the users timezone. Then I wish to check if it is today. When I pass $currentDate into $this->Time->isToday I get nothing back, even thought it is todays date.
If I pass in date("d/m/Y"); it works fine.
I have tried stringToTime also.
$currentDate = $this->Time->format(
'd/m/Y',
$message['Message']['created'],
null,
$userData['time_zone']
);
if($this->Time->isToday($currentDate)){
echo "today";
};
This is the fix I have implemented.
if($this->Time->isToday($message['Message']['created'], $userData['time_zone'])){
echo '<li class="conversation-divider"><span>Conversation started Toady</span></li>';
} else {
echo '<li class="conversation-divider"><span>Conversation started at '.$messageDate.'</span></li>';
};
According to the CakePHP book, you can pass timezone to the 'isToday()' method:
TimeHelper::isToday($dateString, $timezone = NULL)
So - try this:
$today = $this->Time->isToday(
$message['Message']['created'],
$userData['time_zone']
);
Did you make the timezone helper aware of the timezone you used in format()?
You need to at least once set timezone($timezone) for it to know it.
See https://github.com/cakephp/cakephp/blob/master/lib/Cake/Utility/CakeTime.php#L272

Order By Date and truncate date strings in Angular

I have a json file with a released field that comes back with such format:
released: "2002-01-28"
I intend to display them sorted by date (earlier first) and only showing the year. I've used the truncate module (in my example, release: 4) and so far its showing only the first 4 characters, but I haven't succeed using orderby to sort it correctly.
Any pointers?
Also, in some items the released field comes back empty, any quick way to display just a "unknown" instead of a blank space?
Thanks!
<li ng-show="versions" ng-repeat="version in versions | filter: '!file' | orderBy: version.released">
{{version.released | release:4}} - {{version.format}} - {{version.label}}
</li>
Here is a date formatting filter I use. It takes a date and converts it into whatever format you wish, in your case, 'yyyy'. Bind the raw date stamp in your template and then 'orderBy' should work fine. This is how I always do it. Oh, you might not want the replace() function... that was specific to my last project.
.filter('DateFormat', function($filter){
return function(text){
if(text !== undefined){
var tempdate = new Date(text.replace(/-/g,"/"));
return $filter('date')(tempdate, "MMM. dd, yyyy");
}
}
})
You can show unknown by doing {{version.released || 'unknown'}}.
If you only want to show the year do this {{ (version.released | date : date : 'YYYY' ) || 'unknown'}}

Resources