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

lukeify's avatar

It's a date! Challenge: How to format as ISO8601 for API, but store in MySQL format?

I'd like to have my Laravel 6.x application accept and return ISO8601-compliant dates via its API, while continuing to store them in the default MySQL database format, which is Y-m-d H:i:s. The catch is, under no circumstances will I be setting mutators/accessors for every date-related property in my application. This is what the protected $dates array is for, and doing so would not be a best practice as it duplicates code heavily.

I have been able to ensure that the application returns dates to the client in ISO8601 format by overriding the serializeDate function in Model.php like so:

/**
 * Prepare a date for array/JSON serialization by casting it to an ISO8601-conforming string. This overrides the
 * Eloquent `Model` class definition for `serializeDate`.
 *
 * @param DateTimeInterface $date
 *
 * @return string - An ISO8601 string representing the date stored in the database.
 */
protected function serializeDate(DateTimeInterface $date)
{
    return Carbon::instance($date)->toIso8601String();
}
	

and by providing my dates as strings to the Model.php $dates array:

    /**
     * Attributes that should be mutated into dates.
     *
     * @var array
     */
    protected $dates = [
        'beganAt',
        'completedAt'
    ];

Unfortunately, I still cannot send ISO8601-compliant date strings to the application from the client. For example, sending:

{
   "someDate": "2020-04-10T06:47:43.356Z"
}

results with Laravel, more specifically, Carbon, responding with:

{
    "message": "Unexpected data found. Trailing data",
    "exception": "InvalidArgumentException",
    "file": "/var/www/vendor/nesbot/carbon/src/Carbon/Traits/Creator.php",
    "line": 623
}

I have tried setting the $dateFormat property of Model.php to DATE_ATOM, c, and DATE_ISO8601 without success, I have tried overriding the getDateFormat() method, and I have even tried overriding many of the methods in HasAttributes.php trait.

So, how do I go about this?

0 likes
4 replies
Tray2's avatar

This

Carbon\Carbon::parse('2020-04-10T06:47:43.356Z')->format('Y-m-d H:m:s');

Would give you this

"2020-04-10 06:04:43"

Then you can use do something like


public function setBegan_atAttribute($date)
{
  $this->attributes['began_at'] = Carbon\Carbon::parse($date)->format('Y-m-d H:m:s');
}
1 like
lukeify's avatar

Hi @tray2, this doesn't answer my question. As I initially said:

The catch is, under no circumstances will I be setting mutators/accessors for every date-related property in my application. This is what the protected $dates array is for, and doing so would not be a best practice as it duplicates code heavily.

lukeify's avatar

That was a mammoth effort, but yep, I can confirm updating to Laravel 7 fixes this issue. Not exactly desirable if you have a big app though. Thanks!

Please or to participate in this conversation.