Unfortunately the first approach will not work, since browsers do not usually send information about their computerās configured timezone to the server.
This pretty much leaves the second approach as the only possibility.
I believe that there exist many drop-in libraries that allow you to display datetimestamps in a particular timezone in pure browser-friendly JS.
Iāve used moment.js before myself in the past, but it is by no means the only option out there.
BCP47 defines a U extension to the language identifier that is defined in CLDR and is used in the HTTP Accept-Language header. So if the user selects an appropriate language identifier, the requested time zone can be transmitted. As an example en-AU-u-tz-ausyd-ms-metric-fw-mon means āenglish as spoken in Australia with time zone for Sydney, measurement system metric and the first day of the week is Mondayā.
Whilst totally supported in the standard its fair to say that its not an extension often used and probably unreasonable to ask a browser user to do it this way. Totally reasonable to ask an API client to do it though.
My approach relies on the Timex library and the ECMAScript Internationalization API:
When a request comes in, I check get_session(conn, ātmznā). If tmzn is not yet part of my session, I add data-tmzn=ā1ā to my document head. JS then checks document.head.dataset.tmzn on DOMContentLoaded and, if it returns a value, it sends an async GET request to:
Once the server receives this, the timezone can be added to the session, following its verification by calling Enum.member?(Timex.timezones(), iana). From that point onwards, all dates can be rendered server-side with the help of Timex.
This approach may or may not fit your use case, the most obvious issue being that it does not work (at least not out of the box) for the initial page shown to the user.
That was very valuable information! For now, I hacked JQuery+moment solution solution:
let convert_dates = function() {
$(".utc_to_local").text(function(index, utc_date) {
return moment.utc(utc_date).local().format('YYYY-DD-MM HH:mm:ss');
});
};
# for live views
$(document).on("phx:update", convert_dates);
# for regular views
$(document).ready(convert_dates);
But I think Iāll change it later. When I have signing in, Iād like to get timezone from browser via login form and then save it in session. This way, I can format dates server side which wonāt require two additional JS libs.
Iād just like to note that if youāre dealing with timezones then you may be dealing with different cultures and languages. Which also means that the users expectation of date/time format may also be differentā¦
Right, thatās the browser. But the issue is, plug doesnāt run code in the browser, plug runs code on the server, so unless the browser sends that information to the server in the HTTP request, plug canāt do anything about it.
Yeah in @konstantineās reply he built an endpoint to send that data on DOMContentLoaded to the backend.
When a request comes in, I check get_session(conn, ātmznā). If tmzn is not yet part of my session, I add data-tmzn=ā1ā to my document head. JS then checks document.head.dataset.tmzn on DOMContentLoaded and, if it returns a value, it sends an async GET request to:
ā/timezone?iana=ā + encodeURIComponent(Intl.DateTimeFormat().resolvedOptions().timeZone)