Laravel automatically adding time to date

Viewed 3806

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?

4 Answers

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.

Related