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

JeroenVanOort's avatar

Set default JSON date format

Dear Laravel enthusiasts,

As I have asked before I like to format the date fields on my models to include the timezone when using the JSON on my API's.

Yesterday we found out that the solution provided in the other topic doesn't work anymore. It seems to have to do with the Laravel 5.1 update. I would like to now what to do now.

As I understand that people don't look at a topic that is already marked answered, I've opened this new one ;-)

Jeroen

0 likes
7 replies
phildawson's avatar

@JeroenVanOort Before it would be doing this and casting the obj to string so the setToStringFormat would be used.

$attributes[$key] = (string) $this->asDateTime($attributes[$key]);

but it now does this and runs it through serializeDate() which is basically doing ->format('Y-m-d H:i:s') on the date.

$attributes[$key] = $this->serializeDate($this->asDateTime($attributes[$key]));

I can't see why it was changed due to default __toString being 'Y-m-d H:i:s', makes no sense to me.

const DEFAULT_TO_STRING_FORMAT = 'Y-m-d H:i:s';

Here's the commit that changed how it worked.

https://github.com/laravel/framework/commit/fd5e1a7026d88e27794f2db08b788944421275a3

Dates are now serialized using the date format specified via overriding getDateFormat or new $dateFormat property. This provides a more intuitive way of serializing dates, and should match what a new user would expect. Also added new serializeDate() for more granular control over serialization, and to make it easy to store dates in one format while serializing them into arrays and JSON as a separate format.

@TaylorOtwell The last statement on serializeDate() "granular control" doesn't seem to be true as it's using the same dateFormat as how it's stored. If you changed the it through setDateFormat on the model it'll throw a wobbler as soon as it gets to createFromFormat and it doesn't match the value (as it's mixing the usage for format and with creating from format).

return $model->setDateFormat('Y-m'); // fail
(new DateTime('2015-07-02 00:00:00'))->format('Y-m'); // fine
DateTime::createFromFormat('Y-m', '2015-07-02 00:00:00'); // nope 
yeting's avatar

How do i set JSON date format 'U' ?

    protected $dateFormat = 'U';

But it return

InvalidArgumentException in Carbon.php line 414:
Trailing data

in Carbon.php line 414
1. at Carbon::createFromFormat('U', '2015-08-01 07:54:40') in Model.php line 2868
2. at Model->asDateTime('2015-08-01 07:54:40') in Model.php line 2394
3. at Model->attributesToArray() in Model.php line 2371

   /**
     * The storage format of the model's date columns.
     *
     * @var string
     */
    protected $dateFormat;

   /**
     * Convert a DateTime to a storable string.
     *
     * @param  \DateTime|int  $value
     * @return string
     */
    public function fromDateTime($value)
    {
        $format = $this->getDateFormat();

        $value = $this->asDateTime($value);

        return $value->format($format);
    }


    /**
     * Prepare a date for array / JSON serialization.
     *
     * @param  \DateTime  $date
     * @return string
     */
    protected function serializeDate(DateTime $date)
    {
        return $date->format($this->getDateFormat());  // Why this use  the storage format ?
    }
jostyposty's avatar

One could override the serializeDate method on the model:

protected function serializeDate(DateTime $date)
{
    return $date->format('c');
}
3 likes
vool's avatar

For future readers, serializeDate is now passed a DateTimeInterface object

protected function serializeDate(DateTimeInterface $date) {

....

1 like
afzalh's avatar

Put this in your model

protected function serializeDate(\DateTimeInterface $date)
{
    return $date->format('c');
}
4 likes
dtunes's avatar

@ardf16 I wondered about the same thing, I couldn't find any way to do it globally. But a couple of approaches you can try:

  1. Create a BaseModel that extends from Model and define the serializeDate method in the BaseModel class, but you'd need to extend your actual models from BaseModel;
  2. Or, create a Trait and use the Trait in your models;
namespace App\Traits;

use Carbon\Carbon;
use DateTimeInterface;

trait SerializeDates {
    protected function serializeDate(DateTimeInterface $date)
    {
        $format = $this->dateFormat ?? Carbon::ATOM;
        return $date->format($format);
    }
}

// User.php
...
class User extends Model
{
    use SerializeDates;

    // and if you want to override the date format
    public $dateFormat = 'U'; //unixtime stamp
...

Best of luck.

1 like

Please or to participate in this conversation.