Set default database DateFormat to ISO 8601 with timezones in Laravel
Asked Answered
N

6

7

I think the title says it: I want to use ISO 8601 with timezones as default DateTime-Format in Laravels Eloquent. I got this

class mEloquent extends Eloquent {

   protected function getDateFormat()
   {
       return 'YYYY-MM-DDThh:mm:ss.sTZD';
   }

}

All my models will extend mEloquent. But how should I build the tables? Just

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateUsersTable extends Migration {

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::create('users', function(Blueprint $table)
    {
        $table->increments('id');
        $table->string('firstName');
        $table->string('lastName');
        $table->string('email')->unique();
        $table->string('password');
        $table->timestamps();
    });
} ......

as normal? How can I compare this dateformat? Or shoud I just use the default one and save the timezone separately?

Newsworthy answered 29/7, 2014 at 19:52 Comment(2)
Did you find a solution to this problem ?Mcandrew
No, I used SailsJS instead of Laravel back then. This 'solved' the problem.Newsworthy
C
8

It’s really easy if you follow the documents.

PHP date function supports ISO 8601 since PHP5 and we can get it by passing the 'c' format character.

http://php.net/manual/en/function.date.php

Laravel model converts date attributes to Carbon objects. Carbon extends DateTime which has the format function that supports all of the date format characters.

You can easily create an accessor (or even a new custom attribute) to change a date attribute. Then use the Carbon format method to change it to ISO 8601 format.

So in a laravel model, we can do something like this:

public function getPublishedAt8601Attribute()
{
    return $this->published_at->format('c');
}

and then we can access the attribute like this:

// Prints something like: 2016-10-13T21:48:00+03:00
echo $post->published_at_8601;
Cryptic answered 3/11, 2016 at 12:7 Comment(0)
K
6

As mentioned in the docs, add this to your base class 'mEloquent'

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

You can also check out date serializations: https://laravel.com/docs/5.6/eloquent-serialization#date-serialization

Kim answered 3/7, 2018 at 15:53 Comment(2)
This should be the accepted answer as it directly answers the question, not an assumed question.Jigger
This doesn't work because the DateTime::createFromFormat() function does not support the 'c' format. Use DateTime::ISO8601 instead.Rizas
N
5
$date = Carbon::now();
echo $date->toW3cString();

$obj = $this->repository->find($id);
echo $obj->created_at->toW3cString();

Output

2018-04-14T18:35:58+00:00

Nomarch answered 14/4, 2018 at 21:40 Comment(0)
R
2

In your Eloquent model, set the $dateFormat variable to DateTime::ISO8601

    protected $dateFormat = DateTime::ISO8601;

Some others mentioned using the 'c' format but I found that doesn't work because Laravel uses the DateTime::createFromFormat function when converting the DateTime which does not support the 'c' option.

Rizas answered 25/3, 2020 at 15:42 Comment(0)
M
1

Best Solution:

$order_date = $order->created_at;
$date_changed=$order_date->toIso8601String();
Mcadams answered 24/1, 2020 at 13:19 Comment(0)
P
0
    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = ['published_at'];

https://laravel.com/docs/5.6/eloquent-mutators#date-mutators

Primacy answered 2/2, 2022 at 12:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.