Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ezrabutler's avatar

Carbon "Trailing Data" Error

If I run the following line in Tinker, I receive the correct time stamp.

$moment->created_at->format('m/d/Y h:m');

But when I run in the view:

@foreach ($day->moments as $moment) {{ $moment->created_at->format('m/d/Y h:m') }} @endforeach

I receive an error "ErrorException in Carbon.php line 425: Unexpected data found. Trailing data "

(I know that the problem must be with this, because I can retrieve any other field like {{ $moment->place }} .)

Thank you!

0 likes
16 replies
Rogercbe's avatar

What kind of data are you getting when you dd?

dd($moment->created_at);

Does this work?

\Carbon::parse($moment->created_at)->format('m/d/Y h:m');
6 likes
ezrabutler's avatar

@Rogercbe

when I dd($moment->created_at) I get:

Carbon\Carbon {#22421 +"date": "2016-03-10 23:56:08.000000" +"timezone_type": 3 +"timezone": "UTC"

If I put {{ Carbon::parse($moment->created_at)->format('m/d/Y h:m') }} in the view, I receive an error of "Class 'Carbon' not found ".

Thanks anyways!

jekinney's avatar

Created at is already a carbon instance by default, unless you changed it no need for carbon parse.

Use setToStringFormat()

ezrabutler's avatar

@jekinney I actually gave up and changed the database structure to a dateTime('time') as opposed to timestamps() and it worked. I'm sure that when I learn more about Laravel, I'll find out why it didn't work, but for now... I'm getting done what I need to get done. Thank you so much for trying to help!

2 likes
Vetster's avatar

Sorry to bring up an old thread, but here is an elegant solution to timestamps with time zones.

This has to do also with storing the data in the database as timestamp with time zone (postgres). It would return from the database as: 2016-10-05 12:12:10-04 instead of 2016-10-05 12:12:10 which is what Carbon is expecting to format using Carbon::createFromFormat('Y-m-d H:i:s', '2016-10-05 12:12:10').

Looking into some solutions baked into Laravel... a TimezoneAccessor trait may be a solution.

trait TimezoneAccessor
{
    public function getMutatedTimestampValue($value)
    {

        $timezone = config('app.timezone');

        if (Auth::check() && Auth::user()->timezone) {
            $timezone = Auth::user()->timezone;
        }
        return Carbon::parse($value)
            ->timezone($timezone);
    }

    public function getCreatedAtAttribute($value)
    {
        return $this->getMutatedTimestampValue($value);
    }

    public function getUpdatedAtAttribute($value)
    {
        return $this->getMutatedTimestampValue($value);
    }
}

And then, on your Models which you would want to return timestamps in either the users or sites timezone, you would simple use this Trait (effectively overwriting Laravel's built in accessors for the created_at, and updated_at fields.

class User extends Authenticatable
{
    use TimezoneAccessor;
...

}

This will abstract all the mumbo jumbo about time zones away from your app.

5 likes
geeksquads's avatar

Sorry to bark up a year old post... but this shows up on of the top results for many of the Google searches that I've seen when attempting to troubleshoot this error. I thought I'd contribute my finding in case others have a similar issue.

In my case, it wasn't that the postgres data type was a timestamp with a timezone. When I'm working with timestamps with postgres, Laravel/Carbon will format the timestamp like so: 2018-03-12 21:47:33. However, other applications may also write into the same table. This causes issues because the timestamp can be formatted differently. In my case, it was formatted like so: 2018-03-12 21:47:33.296255 (which is still a valid timestamp in postgres.)

I solved the problem by overriding the getDateFormat() function within my model, as documented in this blog post: http://matthewtrask.net/blog/Laravel-Postgres-Timestamps/

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class PostgresModel extends Model
{
    public function getDateFormat()
    {
      return 'Y-m-d H:i:s.u';
    }  
} 

This works for the most part, however this method will break if your table contains timestamps with multiple formats. Not sure what to do about the multiple formats issue yet... other than normalizing all the rows... but other ideas are welcome! :-)

6 likes
Cronix's avatar

@isajid07 That's NOT a good solution. It would be better (and proper) to just update carbon via composer by bumping the version number and composer update. You shouldn't manually do anything to the /vendor folder. Besides, now your composer.lock/yarn.log will be incorrect if you do it the way you suggest because composer doesn't know about your custom changes...

4 likes
Lasvad's avatar

@geeksquads By chance did you figure out a solution for tables containing timestamps with multiple formats? I've been looking around, seen you comment a few times in other locations. I've also read through http://matthewtrask.net/blog/Laravel-Postgres-Timestamps/ . The first solution seems to work, but having to manage created_at and updated_at timestamps is unfortunate. Their second solution works but fails if there are multiple formats in the table OR if there is a insert at a time where milliseconds are 2018-10-10 12:45:38.00000 which will default to 2018-10-10 12:45:38. This breaks things if you've set the fomat to be Y-m-d H:i:s.u... I'm thinking about changing my tables created_at and updated_at to use timestamp(0) which makes the timestamp have no milliseconds. Big migration but I think its a safe way to go. format will be Y-m-d H:i:sfor everything, guaranteed by the column type.

UhOh's avatar

@Lasvad @CanadaStays @geeksquads

Yeah, this was aggravating. So, (after much testing) the solution is not to use the $dates accessor but instead to make your own custom accessors.

So not this...

protected $dates = [
    'start_at',    // no!
]

Instead, this...

public function getStartAtAttribute($value)
{
    return Carbon::parse($value);
}

The 'trailing data' and 'missing data' errors are because the automatic Laravel $dates accessor is trying to create a Y-m-d H:i:s timestamp. If your db field is using timezones this gets all messed up.

So if you have to use timezone fields, no casting, make accessors!

That said, an entirely different approach:

Persist everything as UTC adjusted for your timezone.

// eg. 7AM EST entry, persist this: 
Carbon::parse($time, 'America/New_York')->tz('UTC')

With an additional db field for saving the time zone. Then you can use the two fields together to restore or format the timestamp.

eg. $start_at->tz( 'America/New_York')

Might be cleaner if having to transfer between api's or something.

hope it helps someone, definitely was a pain

1 like
AddWebContribution's avatar

You should try this:

{{ \Carbon\Carbon::parse($moment->created_at)->format('m/d/Y h:m') }}
blackcat's avatar

Hey, guys, this happens when we use Postgres and Carbon. This issue is connected with this PHP bug report I think.

None of the answers above worked for me if you are using TIME WITH TIMEZONES in Postgres as I was you need to set the format to:

protected $dateFormat = 'Y-m-d H:i:s.uO';
2 likes

Please or to participate in this conversation.