-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Respect OS locale when showing datetime strings #116
Comments
This will be trickier than expected. If I remember correctly, then VSCode sadly doesn't really care about the environment to obtain a locale, but instead asks you to configure it (via some preference). And then it only has one locale for all different aspects of localization, i.e. you cannot use English messages with ISO 8601 compatible notation for times, dates and durations. If you want to do the extra work to support glibc locales:
The gist is to use
In my shell:
|
I could try to read @lorenzleutgeb could you maybe also share an example output of |
No. Please read the references I sent. They give a clear priority for these environment variables. You can verify this as follows: $ unset LC_ALL LC_TIME LANG
$ LC_ALL=fr_FR.UTF-8 LC_TIME=de_DE.UTF-8 LANG=en_DK.UTF-8 date --date=2024-01-01
lun. 01 janv. 2024 00:00:00 CET
$ LC_TIME=de_DE.UTF-8 LANG=en_DK.UTF-8 date --date=2024-01-01
Mo 1. Jan 00:00:00 CET 2024
$ LANG=en_DK.UTF-8 date --date=2024-01-01
2024-01-01T00:00:00 CET Oh, and then there's $ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=fr_FR.UTF-8
LC_TIME=en_DK.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=de_AT.UTF-8
LC_MESSAGES=en_US.UTF-8
LC_PAPER=de_AT.UTF-8
LC_NAME=de_AT.UTF-8
LC_ADDRESS=de_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_MEASUREMENT=de_AT.UTF-8
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
$ unset LC_TIME
$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=fr_FR.UTF-8
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=de_AT.UTF-8
LC_MESSAGES=en_US.UTF-8
LC_PAPER=de_AT.UTF-8
LC_NAME=de_AT.UTF-8
LC_ADDRESS=de_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_MEASUREMENT=de_AT.UTF-8
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
$ LC_ALL=fr_FR.UTF-8 LC_TIME=de_DE.UTF-8 LANG=en_DK.UTF-8 locale date_fmt
%a %d %b %Y %T %Z
$ LC_TIME=de_DE.UTF-8 LANG=en_DK.UTF-8 locale date_fmt
%a %-d. %b %H:%M:%S %Z %Y
$ LANG=en_DK.UTF-8 locale date_fmt
%Y-%m-%dT%T %Z Note however that some placeholders (like In case you're implementing this yourself, this means that you have to check for all these three environment variables and their corresponding priority. If neither of these three environment variables are defined, only then you should fall back to whatever is configured in VSCode. More examples at https://www.baeldung.com/linux/locale-environment-variables
Sure. Then the line is just missing, of course. $ env | grep LC_
LC_TIME=en_DK.UTF-8
LC_MONETARY=de_AT.UTF-8
LC_ADDRESS=de_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_MESSAGES=en_US.UTF-8
LC_NAME=de_AT.UTF-8
LC_MEASUREMENT=de_AT.UTF-8
LC_NUMERIC=fr_FR.UTF-8
LC_PAPER=de_AT.UTF-8
$ unset LC_TIME
$ env | grep LC_
LC_MONETARY=de_AT.UTF-8
LC_ADDRESS=de_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_MESSAGES=en_US.UTF-8
LC_NAME=de_AT.UTF-8
LC_MEASUREMENT=de_AT.UTF-8
LC_NUMERIC=fr_FR.UTF-8
LC_PAPER=de_AT.UTF-8
If someone is fine with using one locale consistently for all categories (time, monetary amounts, paper size, ...) which is actually quite likely, than they'll be inclined to just set |
That's such helpful info, thank you! 🙌 Do you think you could hit me with a shell script that returns a Resources: |
I think that's impossible, since that encoding does not allow to set a particular date/time format directly, see tc39/ecma402#554 Best solution I see is: function format(date) {
const glibcLocale = /* read environment to get glibc compatible locale */;
const bcp47Locale = /* simple function that converts glibc locale to BCP 47 locale */;
/* think about fallback so that you always have a valid bcp47Locale */
return (new Intl.DateTimeFormat(bcp47Locale).format(date));
} If that'd be good enough for you, I can fill in the blanks and send you that script. |
Sounds good. I don't need the full formatting function, just the shell script that will be run to source it from the OS (plus any filtering/clean-up) or just a link to any native nodejs API doing the same job, if available. I'll handle the glue code beyond that. I'll add you with a For context, this is my formatting function and for completion this is the place you spotted in the UI and prompted you to report the issue in the first place (its called in more places of course). |
Yeah, of course they are in there. I tacitly implied that all along. However it seems that you are comparing I also continued experimentation yesterday, and am not so positive about the result. A conversion from libc locale to BCP47 and using |
Very, very rough: const util = require('node:util');
const exec = util.promisify(require('node:child_process').exec);
/*
full long medium short
d_t_fmt
date time
long/full long/full date_fmt
medium medium d_t_fmt
medium none d_fmt
none medium t_fmt
*/
async function localeFormat() {
const { stdout } = await exec("locale d_t_fmt");
return stdout;
}
function getLibcTime() {
return process.env["LC_ALL"] || process.env["LC_TIME"] || process.env["LANG"];
}
/**
* glibc locales follow the format
*
* language[_territory[.codeset]][@modifier]
*
* For primitive conversion to BCP47 we discard `codeset` and `modifier`
* (including their respective prefixes `.` and `@`) and replace
* `_` by `-`. This is wrong, but works fairly well.
*
* See <https://www.gnu.org/software/libc/manual/html_node/Locale-Names.html>
*
* The proper (but complicated) way of doing this right is described in
* <https://wikinew.openoffice.org/wiki/LocaleMapping>
*/
function libcToBCP47(libc) {
return libc.replace(/(\.|@).*/, "").replace("_", "-");
}
function format(date, locale) {
return date.toLocaleDateString(locale, {
weekday: 'short',
month: 'short',
year: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZoneName: 'shortGeneric',
});
//return (new Intl.DateTimeFormat(locale, { dateStyle: 'short' }).format(date));
}
let date = new Date(2024, 1, 1);
console.log(format(date, libcToBCP47("en_DK.UTF-8")));
//console.log(date);
//console.log(libcToBCP47("en_US.UTF-8@lel"));
//console.log(libcToBCP47("en_DK.UTF-8@lel"));
//console.log(format(new Date(), libcToBCP47(getLibcTime())));
//console.log(format(new Date(), "dk"));
//console.log(format(new Date(), "en-DK"));
//console.log(format(new Date(), "de-AT"));
|
Results: 🚀 Enhancements
|
This applies mostly for the patch detail page, but as long as we pass the right param to the one datetime formatting function we call everywhere we'll be fine.
The text was updated successfully, but these errors were encountered: