In my Laravel application I have a form in which you put the date to capture the date of an expense. This field is a MySQL DATE field so the format is yyyy-mm-dd.
The timezone in my application is set within config/app.php
like so.
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'Europe/London',
Fairly recently in Britain we entered into British Summer Time (as we do every year) and this raises my actual question.
A user used a date picker to select 2022-04-04 and this was entered into the database as 2022-04-04.
The issue is with the return value from an accessor.
/**
* Force date format.
*
* @param [type] $value
* @return void
*/
public function getDateAttribute($value)
{
return Carbon::parse($value)->format('d M Y');
}
(Note that the date field has also been cast to a Carbon instance.)
This comes back as 03 Apr 2022, and if you add Y-m-d H:i:s
it comes back as 2022-04-03 11:00
Given the picture above can I assume that Europe/London
is equivalent to GMT
?
CodePudding user response:
Dates and times get very complicated very quickly.
Unix and Javascript have similar notions about the representation of both which does not allow for representations of dates prior to 01/01/1970. Modern relational databases OTOH do allow for this (some even handle oddities like the Gregorian/Julian change).
It looks like the stored value has been cast crudely to a Unix timestamp then Carbon has converted from this using GMT rather than Europe/London.
The timezone Europe/London has daylight savings time, while GMT does not - so they are only equivalent for the winter months. GMT is calculated slightly differently from UTC but for most pruposes they can be considered equivalent.
The timezone in my application is set within config/app.php like so
But is that what Carbon is using?
You should have your default timezone set in your PHP.ini (it causes a performance overhead if its not set - so always a good idea to set some value). You can override this in code using dadte_default_timezone_set(), in specific APIs and/or date time strings.
Also, if you know something is going to convert a date string into a time value, then explicitly add a time after 2am.
CodePudding user response:
I strongly suggest to store all dates in UTC as it's the only reliable way to avoid confusion.
With Javascript you can get the UTC value of a date input this way:
let d = new Date('2022-04-22');
let utcdate = d.toISOString();
You can convert it back in to the local time for the user in the browser by simply creating a new Date object:
let d = new Date(utcdate).toLocaleDateString();