statamic / cms

The core Laravel CMS Composer package
https://statamic.com
Other
4.02k stars 528 forks source link

Configured timezone is not respected in the API #4270

Open MrMooky opened 3 years ago

MrMooky commented 3 years ago

Bug Description

When creating a date field in a fieldset, it uses UTC by default and not the timezone set in config/app.php. In my case it is 'timezone' => 'Europe/Berlin'. When setting the date, for example 2021-09-16, the output is "2021-09-15T22:00:00.000000Z".

This makes it more complicated to compare dates with now(). So the bug, at least it seems to me, is that Statamic does not respect the timezone set in my app. Basically, I have to do this in order to make it work:

Carbon::parse($response->json()['data'][0]['starts_on'])->timezone(config('app.timezone'))

This seems to be related to the Content API only.

Environment

Statamic 3.2.4 Pro Laravel 8.61.0 PHP 8.0.10 jacksleight/bard-paragraph-style 1.0.0 jonassiewertsen/statamic-livewire 2.7.0 octoper/statamic-blade-components 1.0.1 optimoapps/statamic-bard-text-align 1.0.2

Install method:

jasonvarga commented 3 years ago

Like you've said, it looks like this only applies to the API.

lotarbo commented 2 years ago

mb its not a bug, laravel use iso-8601 in resources, so, your date is converted to UTC in API. You need to convert date from API to your timezone

QuentinGab commented 2 years ago

You should never store your dates in another timezone than UTC, Carbon documentation links to this great article to explain why https://kylekatarnls.medium.com/always-use-utc-dates-and-times-8a8200ca3164. The best way to deal with dates is to convert and format it to the right timezone when displaying the date to the user. In Laravel it means keeping the timezone in config/app.php set to UTC.

MrMooky commented 2 years ago

I'm not displaying the dates to the user. It's essentially a comparison in my code that something should happen only if the date condition is met. When using UTC and users from Europe/Berlin are using the site, the rendered data is not correct. Right now, UTC is 15:45, while EU/Berlin is 17:45.

ryanmitchell commented 10 months ago

If you want date formats in JSON to be your timezone and not UTC (which is Carbon's default), you could make an API middleware and add:

        \Carbon\Carbon::serializeUsing(function ($date) {
            return $date->toIsoString(true);
        });

the true in the param keeps the timezone offsets, see: https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Traits/Converter.php#L519