|

Laravel timezone – important settings

I would like to share one situation that I had while working on one of my projects and how timezone had effect on this.

Project I was working now was about synchronysing data between two applications. Data was synced in raw format which means completelly same values for fields like created_at and updated_at columns will be transfered.

After finishing synchronisation scripts and putting this in production and running first syncs, I’ve noticed that I have small difference in synced tables. I was syncing whole day data. At first it was tricky to notices because when I was filtering for example by category I had same number of records, but total for that day was different in few items, maybe less then 100.

This pointed me have a look at created_at fields because data was synced based on this fields. Synchronisation was done each day for previous day. Some of the records goes to next day because value in created_at column was different then in original table. Difference was actually one hour.

First thing that came in my head was to have a look at timezone in both projects, also both projects were Laravel apps. In first project timezone was Europe/Belgrade, while in second was UTC. The problem was with settings in first application where timezone was Europe/Belgrade.

So, what actually happened?

Laravel is asuming that all data saved in database is in UTC. When reads data from database if timezone is not UTC it will convert to timezone that is in your config/app.php file, in this case +01:00 for Europe/Belgrade.

Why is this bothering me? When we are saving data via Laravel models, it doesn’t convert to UTC even if timezone setting is differently set up. I belive that this logic is inconsistent and that logically consistent behaviour would be:

  // If app.timezone = 'Europe/Belgrade'

  // When WRITING:
  Carbon::now()14:00:07 Europe/Belgrade
  Convert to UTC → 13:00:07 UTC
  Save to DB → 13:00:07

  // When READING:
  Read from DB → 13:00:07
  Assume UTC → 13:00:07 UTC
  Convert to app.timezone → 14:00:07 Europe/Belgrade
  Perfect match!

  Or alternatively:

  // Treat app.timezone as database timezone consistently

  // When WRITING:
  Carbon::now() → 14:00:07 Europe/Belgrade
  Save to DB → 14:00:07 (as Belgrade time)

  // When READING:
  Read from DB → 14:00:07
  Assume app.timezone → 14:00:07 Europe/Belgrade
  No conversion needed!

Also, this can be resolved by adding method serializeDate in model. In that case when reading data laravel will not assume that data is saved in UTC, it will took timezone from your config/app.php file.

    protected function serializeDate(\DateTimeInterface $date)
    {
        return $date->setTimezone(config('app.timezone'))->format('Y-m-d H:i:s');
    }

Anyway, few hours of investigation and work with Laravel timezone. 🙂

Found this useful? Share it with your network.

Similar Posts

  • LaraDumps Debugging Game Changer

    LaraDumps really changed how I debug Laravel framework. I spent years using dd() and dump() like everyone else. Sprinkle them around, refresh the browser, stare at the output, delete them, repeat. It works, but it’s not exactly elegant. Then I found LaraDumps. It’s a desktop app that catches all your dumps, queries, logs, and pretty much anything you throw at it – in real time. No more refreshing. No more losing your…

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.