Carbon in Laravel 4 InvalidArgumentException - Unexpected data found. Trailing data - php

I'm trying to get an Eloquent query result for DB::raw("DATE_FORMAT(created_at, '%m-%d-%Y %r') AS created_at") but each time I get this exception from Carbon:
InvalidArgumentException
Unexpected data found. Trailing data
If I change it to just created_at instead of employing MySQL's DATE_FORMAT() function, then it gets the data without issue.
I've not only done this sort of date formatting without issue before, but I checked every field in the database table (there are only 10 for this seed) and each is a standard valid date, so I'm wondering why Carbon is pitching a fit.
Running this in Laravel 4.1.

In an Eloquent query result (model) every date field is a carbon object, it means, if you query a model which contains any timestamp field like created_at, updated_at (basically created using timestamps() during migration) and deleted_at, Laravel converts them to a Carbon object and you may use any public methods of Carbon, for example:
$user = User::find(1);
// '2014-04-20 19:02:09' will become 'Apr 20, 2014'
$user->created_at->toFormattedDateString();
So, you may directly use any public method of Carbon on a timestamp field available in a model. If you try this:
dd($user->created_at);
Then the output will be:
object(Carbon\Carbon)[456]
public 'date' => string '2014-04-20 19:02:09' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)
So, if you want to format a date, you may use:
// outputs like: 'Sunday 20th of April 2014 07:02:09 PM'
$user->created_at->format('l jS \\of F Y h:i:s A')
Update:
If you want to change this behavior, means that, if you want tell Laravel that, which fields should be converted automatically to Carbon object then you may override that by creating a method in your model like:
public function getDates()
{
// only this field will be converted to Carbon
return array('updated_at');
}
To totally disable date mutations, simply return an empty array from the getDates method. For more details, check Date Mutators on Laravel website.

I realise the original question refers to MySQL but I had the same error with MSSQL. The problem turned out to be that MSSQL's datetime column type has a precision of .001 seconds but I was setting my model's format to no precision:
protected function getDateFormat()
{
return 'Y-m-d G:i:s';
}
By using the newer DateTime2 column type and turning off the precision, I fixed the error. I.e.
datetime2(0)
You could instead change the format in getDateFormat, of course.

If it helps anyone else, I got the same error when attempting to copy a date.
$user->last_login = Carbon::now();
if ($user->first_login < Carbon::createFromDate(2000, 1, 1)) {
// This is the users first login
$user->first_login = $user->last_login; // FAILS!
}
Turns out Laravel casts the value of $user->last_login to a DateTime+Timezone string. It's no longer a Carbon object.
You could fix the error by using copies of a single Carbon object (example below), or by setting up mutators (setters) on the underlying model.
$now = Carbon::now();
$user->last_login = $now;
if ($user->first_login < Carbon::createFromDate(2000, 1, 1)) {
// This is the users first login
$user->first_login = $now;
}

Related

Carbon time format

I save the user photo with Carbon in laravel 9
$user->photo_verified_at = Carbon::now()->timestamp;
But I get this output from database:
Error Message : ORA-01843: not a valid month
Position : 42
Statement : update "USERS" set "PHOTO_VERIFIED_AT" = :p0, "USERS"."UPDATED_AT" = :p1 where "ID" = :p2
Bindings : [1672340645,2022-12-29 19:04:05,25]
If you a look at the data for created_at and updated_at in the database, they have the following format:
29/12/22 18:30:43,000000000
How is it possible to set Carbon to return in that format?
Carbon::now()->timestamp->format('dd/mm/yy H:i:s')
it returns
Error: Call to a member function format() on int
You should be fine with just Carbon::now() or now() (it is a helper function calling Carbon::now())
I am not exactly sure what you are storing there, if it is a timestamp that is literally a number, for example, 13102321 (just a made up number from me), it is the seconds that literally passed since a known date (I think it is January 1st, 1970 or something like that).
So, if you exactly want that fomat, it is as easy as reading the documentation, it will state that you can use the normal PHP's Date format:
$formatedString = now()->format('d/m/Y H:i:s,u000');
You have to add 3 more 0, as it has 9 0, that is nano seconds, super weird, but it is exactly the format you want...
You can also try out just using now() or any method that returns a literal Carbon object, it can or cannot work, depends how you have your model's attribute casted/declared.

Laravel saving data with Carbon::now() is formatted differently to created_at

I'm working with a Laravel project and time zones (I know time zones are a pain), and what's occurred to be is that one of my custom columns in my table, the column called last_checked which is stored as a timestamp appears to be formatted differently from the created_at, and it means that my time zone parsing isn't parsing the date at all for the user's time zone.
Here's what I mean...
When storing a record, I set the date and time:
$uptimeMonitor = Monitors::where('id', $monitor['id'])
->get()
->first();
$uptimeMonitor->last_checked = Carbon::now();
$uptimeMonitor->save();
But when I retrieve the result, looking in my network request, I'm seeing this format:
2021-04-05 11:46:54
But when I look at both the created_at and updated_at columns, they're in this format:
2021-04-05T10:01:16.000000Z
So the question here is, what am I doing wrong with saving my data? Both formats seem to be visually shown the same in the database, but for some strange reason, the first example isn't parsing correctly.
Carbon uses the default DateTime PHP object, so use the date_default_timezone_set() function, for example: date_default_timezone_set('UTC');
or you define it AppServiceProvider App/Providers/AppServiceProvider.php
public function boot()
{
date_default_timezone_set('UTC');
}
Or you can use setTimezone of carbon method
echo Carbon::now()->setTimezone('UTC')->format('H:i');
Try this
$uptimeMonitor = Monitors::where('id', $monitor['id'])
->get()
->first();
$uptimeMonitor->last_checked = Carbon::now()->setTimezone('UTC')->format('Y-m-d H:i:s');
$uptimeMonitor->save();
Note my default app timezone is UTC just find your default timezone
and set it in `setTimezone('UTC');
You need to add all the datetime properties in your $casts model protected member:
https://laravel.com/docs/8.x/eloquent-mutators#date-casting
All is OK in your DB, it's just Laravel model has to know it's a date to format with the full ISO-8601 string in your JSON.
Side note, you still should have "UTC" as your default in config/app.php, it does not prevent from having any timezone handling for particular cases, or to handle users timezone, on the contrary.
If your dates output string as GMT+1 by default, it's very likely a configuration mistake.

Laravel automatically adding time to date

I seem to have a problem with my Laravel application, and I can't for the life of me figure out whats going on.
I have a simple date field in my MySQL database, its data type is just date, and for this example the value is 2020-08-13, but for some reason, when I try to access the date, it adds a timestamp on the end, minuses 1 day and throws a Carbon trailing data error.
It is definitely this date, because when I soft delete it, the error disappears.
As an example, the error for this date is
Carbon\\Carbon::rawCreateFromFormat('Y-m-d', '2020-08-12T23:0...', NULL)
So as you can see, it's removing a day and trying to format at 11pm the night before?
I have had similar issues to this before where Laravel was adding 0000-00-00 to the date, so I had to remove it in my accessor, but now that its throwing 11pm, my string replace doesn't work anymore. I can obviously just change the string replacer to look for 11pm, but I don't want to have to fix this every time the format changes.
My accessor code is as follows
public function getDateAttribute($value){
//String replace and remove the time from the value if it exists
$value = str_replace(' 00:00:00', '', $value);
return Carbon::CreateFromFormat('Y-m-d', $value)->format('d/m/Y');
}
Has anyone had an error like this before, or have any idea whats going on?
Before Laravel 7, dates would be serialized to a format like the following :
2019-12-02 20:01:00
But, Laravel 7 uses a new date serialization format when using the toArray or toJson method on Eloquent models, with ISO-8601 date format. This ISO-8601 dates are always expressed in UTC, like this :
2019-12-02T20:01:00.283041Z
If you would like to keep using the previous behavior you can override the serializeDate() method on your model, add this into your model :
use DateTimeInterface;
protected function serializeDate(DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}
first define you column to $dates property on your model :
$dates=['date']
then specify your date format by accessor :
public function getDateAttribute($value){
return $val->format('d/m/Y');
}
public function getDateAttribute($value){
// return 2020-08-17
$date = date('Y-m-d',strtotime($value));
return $date;
}
Make sure of the config file. You will find there a function of local time that can change its value from UTC to the local time of your country
config / app.php
'timezone' => 'Asia/Riyadh',
it's removing a day and trying to format at 11pm the night before
That's clearly a timezone shift (you're likely in GMT+1) and this is a shift to GMT+0 (UTC).
You should not trim the time to force "00:00:00" because this will only work in 1 timezone (there is no worldwide-midnight-moment, there is a different midnight moment in each timezone for each day), while your app now or later may handle multiple timezones. You should rather save the timezone ("Europe/London" for instance) in an other DB column and so you'll keep the complete information and when retrieving your date, you can calculate on the fly the midnight from (before) this date-time according to the user timezone.

Laravel4 - handling date format between whole application and mysql

In laravel 4 i have lots of database fields that having date type and datetime . but i am need to show date format like dd/mm/yy H:i:s like any format and also have to handle date formation on insertion and update. Is they any way to get works in one place?
Yes you can do that, by creating mutator method in your model; for example, if you have a Post model and has a date_of_birth property and you want to set the date in yyyy/mm/dd H:i:s but user is probably providing the date in a different format. In this case crate a mutator method in the Post model like this:
public function setDateOfBirthAttribute($value)
{
// value will be the given date by user
$dt = \Carbon\Carbon::createFromFormat('Y/m/d H:i:s',$value)->toDateString();
$this->attributes['date_of_birth'] = $dt;
}
To access the date just create an accssor method like:
public function getDateOfBirthAttribute()
{
return \Carbon\Carbon::createFromFormat('d-m-Y H:i:s', $this->date_of_birth);
}
Now the date_of_birth will be inserted using the format that you have used in the mutator method and when you'll show that date, it'll be displayed using the format that you have used in the accessor method. You may also check the Date Mutators.
A must have package for dates is Carbon. Take a look at the documentation on GitHub: https://github.com/briannesbitt/Carbon

PHP using Laravel 4 and Carbon will not print out a DateTime field from my Database

I am building a PHP application with Laravel 4.
I am getting errors when I try to print out a DateTime record from the Database though.
{{ $user->created_at }}
Gives me this error
InvalidArgumentException
Trailing data
open: E:\Server\htdocs\projects\timeclock\www\vendor\nesbot\carbon\src\Carbon\Carbon.php
Very frustrating!
An example value from that Database field is: 2013-08-31 20:50:25.
You are missing the milisecond data on the time stamp, you need to use:
Carbon::createFromFormat('Y-m-d H:i:s.u', $value)->format('d/m/Y H:i:s');
You have to format it:
{{ $user->created_at->format('h:i:s') }}
The PHP docs has a list of all the codes available to use as a format.
I have the same issue.
And I found that this is caused by my timestamp data in database.
2013-12-13 22:40:50.561709 <- this one will cause the issue.
2013-12-13 22:40:50 <- this one will not.
Timestamp value with millisecond causes this issue.
Column which is converted to Carbon object can not have millisecond timestamp.(default: created_at, updated_at).
http://readouble.com/laravel/4/2/0/en/eloquent.html#date-mutators
If Carbon Object is not necessary, you can disallow auto-converting.
class SomeModel extends Eloquent {
public function getDates()
{
return array();
}
}
But it also make Carbon methods(ex:->format()) unavailable. You have to format timestamps in other way.

Categories