Here is the situation:
I have occurred_at
dates stored in my database in UTC. I'm using laravel to write an API method that returns records that contain these occurred_at
fields. They are currently being returned via JSON in a string format (what the PHP Carbon library outputs), ex:
"occurred_at":"2015-04-14 00:25:20"
This date "occurred" at 00:25
(12:25 AM
) in UTC timezone, but actually at 2015-04-13 17:25
(5:25 PM
) in Pacific (PST) timezone.
I am using angular to consume the JSON, and figured I would use the angular-moment library to convert the UTC to local. But it's not working. Both the angular-moment and native angular filters output the same thing:
<span>{{evt.occurred_at | amDateFormat:'L LT'}}</span>
<span>{{evt.occurred_at | date:'MM/dd/yyyy @ h:mma'}}</span>
Output:
2015-04-14 00:25:20
Still in UTC. In my angular app code I even have the UTC preprocessor setup to read them in as UTC, but they don't display as local times:
.constant('angularMomentConfig', {
preprocess: 'utc'
})
There HAS to be a standard way of going about this - storing datetime values in UTC in the database but displaying them as a local time to the user. Do I need make some changes server side? Client side? What is best practice to utilize the "it just works" methods, without writing a ton of code for each date I want to display?
Currently, in non-angular projects, I am using what I consider to be a 'hack' by applying a css class to every span that I want to convert the time to local:
$('.utc-dttm').each(function () {
var t = moment.utc($(this).text()).local();
$(this).text(t.format("L") + ' ' + t.format("LT"));
});
But I'd argue this is the wrong way of going about it.
Since a valid JSON datetime string is formatted as ISO-8601 format, you should have Carbon convert the date values to this format before returning it to the client via toIso8601String
, like:
$occurred_at->toIso8601String();
This will output the date string as
2015-04-14T00:25:20Z
which javascript and any date extension libraries should natively parse as being in UTC timezone and adjust to client timezone when output to user.