How does Chrome determine how dates are formatted with method toLocaleString()? - javascript

I am displaying dates client-side via the toLocaleString() method from Intl.DateTimeFormat.
The page is accessed via Chrome from "German" timezone.
The OS (Ubuntu) language is set to English (US). The region is set to Germany.
The code for date display is like this:
const date = new Date();
const displayDateStr = localeDate.toLocaleString(date);
console.log(displayDateStr)
The formatting is shown as "9/28/2022, 3:00:20 PM", which is probably due to the Chrome language being set to English (US) and hence expected.
If I go to Chrome DevTools -> Sensors pane (Cmd + Shift + P and type sensors), I can overwrite the "location".
Now if I select "Berlin" for location, both the time-zone and the display format are displayed in German (i.e. "28.9.2022, 15:00:20").
The change of location in Chrome DevTools (affects time-zone and date formatting) behaves different than a change of the OS Systems location (affects the time-zone, but not the formatting).
Now my confusion is where the default language for date formatting is generally taken from. Is using the default format reliable or is it best practice to specify it somehow manually for users?

Related

Javascript date toLocaleString ignores locale

I have en_GB as locale on both my system and my browser.
browser
system
When I run (new Date()).toLocaleString() in the browser console I get "12/1/2021, 1:56:32 PM" aka the en_US format. However, if I set the locale via Chromium Dev Tools Sensors tab to en_GB and reload the page, the function returns "01/12/2021, 14:05:02" aka the proper en_GB formatting.
Overriding locale with Dev Tools
So my questions is whether or not this is an issue with my system/browser. If it's not an issue with my configuraiton, then how why does that dev tools feature fix the issue? How exactly does it change the global javascript values and why doesn't the browser set those automatically according to my default language?
I am aware of workarounds such as passing the navigator.language manually as an argument to toLocaleString function or using a library like moment or dayjs to manage my dates and formatting, but this questions just about the unpredictable behaviour of toLocaleString as I have described above.
Thanks.
Turns out I have had export LANG=en_US.utf8 in my .bashrc. Since it is apparently sourced before starting any program on my system, the browsers used en_US instead of my actual system language.

Does Intl.DateTimeFormat()'s `dateStyle` and `timeStyle` use the format defined in the OS preferences?

In the past I've always said it's not possible to display the date/time in the format as defined by the user in their OS preferences. For example, I may have EN-US as my language/region but prefer to use a 24-hour time format. Or, I may have changed the short date format from mm/dd/yyyy to mm/dd/yy.
Has this changed now that Intl.DateTimeFormat can use dateStyle and timeStyle values? Note: these options are not supported in all browsers at the time of writing this.
The values for dateStyle and timeStyle are:
full
long
medium
short
These predefined formats (full, long, etc) can be defined by the user in their system preferences, like this.
Do the values of dateStyle and timeStyle use the same format as defined in the OS preferences for the values of full, long, etc?
Here's an example. In the snippet below I have used toLocaleString to display the current date/time. For the options I have passed dateStyle: 'long' and timeStyle: 'long'. Will this use the same format as defined in my OS preferences even if I change the 'long' format to a custom format?
const event = new Date();
console.log(event.toLocaleString(undefined, { dateStyle: 'long', timeStyle: 'long', timeZone: 'UTC' }));
Sometimes.
dateStyle and timeStyle addition is a stage 3 proposal, so they are not yet fully finalized. That said, the question is not really about these specific options, but rather about how the engine decides to retrieve the default locale settings and whether it includes the customizations the user has made.
The ECMAscript specification describes the default locale as implementation-specific, so it’s up to the engine to make this decision. See more details in another answer.
It makes a lot of good sense to use the user’s OS preferences, and Edge does so. However, Chrome and Firefox allow the user to choose the browser language independently, and this causes inconsistencies with how the rest of the application behaves. See a more thorough discussion in Firefox bug 1366136.
So to summarize, the answer is dateStyle and timeStyle will sometimes take user’s OS preferences into account, and sometimes they will not.

Chrome cannot get TimeZone name correctly after changing the TimeZone of computer

I have a snippet code in javascript as shown below:
$(document).ready(function () {
var day1 = new Date();
});
Now I open a browser (in this case I use FireFox) and the current TimeZone of my computer is UTC +10:00 Hobart. Then I view the day1 javascript variable in debug mode, it displays its value as image shown below.
The TimeZone name of UTC+10:00 Hobart is Tasmania Standard Time. FF gets the correct name and as my expected too.
Next, I will chang the TimeZone on my computer to UTC+10:00 Canberra, Melbourne, Sydney while FF browser is being opened. Then I refresh FF browser by pressing Ctrl+F5 and view day1's value in debug mode again.
As you can see, FF updated the new correct TimeZone name as AUS Eastern Standard Time. It worked as my expected too.
MS Edge and IE worked as the same way with FF.
BUT, Chrome worked in a different way.
The new TimeZone name that Chrome returns to me is Local Daylight Time, not AUS Eastern Standard Time as my expected and as the other browsers (FF, MS Edge, IE) did.
Why does not Chrome return "AUS Eastern Standard Time" name?
Is there any way can solve this case for Chrome?
Unfortunately, the implementation of time zone name is not standardized. The ECMAScript spec allows it to be anything the vendor wants it to be. It's not even just different across browsers, but also across different versions of the browser, and across operating systems.
From ECMA-262 (5.1) Section 15.9.5.2 (emphasis mine)
Date.prototype.toString()
This function returns a String value. The contents of the String are implementation-dependent, but are intended to represent the Date in the current time zone in a convenient, human-readable form.
If what you're trying to do is to detect the user's time zone, there is a newer standard for retrieving the time zone name, as an IANA time zone identifier (ex, Australia/Sydney), which you can do like this:
Intl.DateTimeFormat().resolvedOptions().timeZone
However, not all browsers have implemented this yet. There are libraries that can guess at it though, which you can read about here.

Date format on client browser

I am getting a date from the server as a javascript string(GMT) or unix timestamp(GMT).
I can convert it to a javascript date object with
var date = new Date(string) or var date = new Date(string)
This gives me the date variable with proper system time-zone's time.
Currently I am displaying this- date.toLocaleString()
Which gives me a nicely formatted date/time according to my system locale and time zone.
I am using this to automatically accomodate for DST if the client browser follows it.
Previously I was required to display this date only in EST, but when the US time started following EDT, I was told to display it in EST. I think this approach would simplify displaying the time/date acoording to user's system time setting.
Is there any disadvantage or possible bug accociated with this approach?
If yes, what would be the best way to display this date in the browser, so that it displays correctly according to the timezone(accomodating DST if any) in which the user(cient browser) is?
As pointed out in the comments, the output may be different depending on the users settings. A more reliable and flexibe solution is moment.js, which is a great library.
moment("2013-04-04", "YYYY-MM-DD").format("MMM Do YY"); //"Apr 4th 13"

Javascript on Mac (Safari) toLocaleTimeString() oddities

We have a simple function the works out a duration, it works fine in every browser apart from Safari on a Mac (works in chrome on the mac, works on Safari on the PC)
For example,
new Date().toLocaleTimeString()
We expect this to give a time formatted like this:
11:59:25
However, on the Mac Safari we get this
11:59:25 GMT+01:00
Any calculations we do on these times are one hour out (its adding the hour onto the calculation)
e.g.
11:59:25 - 11:59:25 = 01:00:00 (should be 00:00:00)
Any ideas?
Why is it adding the time zone to the string? this caused us a little issue with our database
Why is it adding an hour to the sting?
Why just in that one bloody browser!
Thanks for your time.
The toLocaleTimeString method relies on the underlying operating system in formatting dates. It converts the date to a string using the formatting convention of the operating system where the script is running. For example, in the United States, the month appears before the date (04/15/98), whereas in Germany the date appears before the month (15.04.98).
Methods such as getHours, getMinutes, and getSeconds give more consistent results than toLocaleTimeString. Use toLocaleTimeString when the intent is to display to the user a string formatted using the regional format chosen by the user. Be aware that this method, due to its nature, behaves differently depending on the operating system and on the user's settings.
Source: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString
In OS X, time format can be fine tuned by Apple menu > System Preferences > Language & Region > Advanced > Time. The format used by toLocaleTimeString() is the Long format. You can adjust the format as desired for your needs, however keep in mind this change will be effective system wide.
Source: Apple Support - Customize Formats

Categories

Resources