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?