Search code examples
laraveldatetimetimestampmigrationphp-carbon

Carbon::now() wrong date and time


Current UTC time is: 2022-08-19 00:50

When I create a new record in my database I set created_at like:

'created_at' => Carbon::now()

But it stores Datetime like this -> 2022-08-18 20:50

Anyways, after couple of minutes I update this record and set updated_at like:

'updated_at' => Carbon::now()

And it stores it like this -> 2022-08-19 00:50 which is correct but not completely, because couple of minutes passed and it should be like 2022-08-19 00:53

Here is my migration file:

public function up() {
    Schema::create('items', function (Blueprint $table) {
        $table->id();
        $table->timestamp('created_at');
        $table->timestamp('updated_at')->nullable();
    });
}

/config/app.php:

'timezone' => 'UTC',

My Item Model:

class Item extends Model {
    use HasFactory;

    public $timestamps = false;
}

Seriously, whats wrong with this datetime thing in laravel? Why it doesn't work like every other frameworks?

Note: I'm sick of laravels default $table->timestamps() it works even worse.


Solution

  • It was a problem related to database.

    When you create a column this way $table->timestamp('created_at'), it creates a column in database with this structure:

    |----------------------------------------------------------------------------|
    |    Name            Type        ...        Null        Default              |
    |----------------------------------------------------------------------------|
    |    created_at      timestamp               No         current_timestamp()  |
    |                                                                            |
    |----------------------------------------------------------------------------|
    

    If you pay attention to the Default column, you find out that this function uses the mysql server timestamp to set value for the created_at column and ignores your entry in laravel create() method.

    To fix this problem you only have to set created_at to a nullable column like so:

    $table->timestamp('created_at')->nullable();