Changes in V8/ICU behaviour should be detected&tested&documented|overridden

Version

v14.17.6, v16.14.1, v18.0.0-pre

Platform

Linux nepbook 5.17.0-gentoo-nep #1 SMP Tue Mar 22 08:34:44 +08 2022 i686 Intel(R) Atom(TM) CPU N270 @ 1.60GHz GenuineIntel GNU/Linux

Subsystem

intl, deps

What steps will reproduce the bug?

Example 1

console.log(new Intl.DateTimeFormat('en', { calendar: 'iso8601' }).resolvedOptions().calendar);
console.log(new Intl.DateTimeFormat('en', { calendar: 'BAD_BANANA' }).resolvedOptions().calendar);

node v14.17.6:

gregory
file:///tmp/calendar-14.17.6.mjs:2
console.log(new Intl.DateTimeFormat('en', { calendar: 'BAD_BANANA' }).resolvedOptions().calendar);
            ^

RangeError: Invalid calendars : BAD_BANANA
    at new DateTimeFormat (<anonymous>)
    at file:///tmp/calendar-14.17.6.mjs:2:13
    at ModuleJob.run (internal/modules/esm/module_job.js:170:25)
    at async Loader.import (internal/modules/esm/loader.js:178:24)
    at async Object.loadESM (internal/process/esm_loader.js:68:5)

node v16.14.1:

node v18.0.0-pre:

iso8601
file:///tmp/calendar-18.0.0.mjs:2
console.log(new Intl.DateTimeFormat('en', { calendar: 'BAD_BANANA' }).resolvedOptions().calendar);
            ^

RangeError: Invalid calendar : BAD_BANANA
    at new DateTimeFormat (<anonymous>)
    at file:///tmp/calendar-18.0.0.mjs:2:13
    at ModuleJob.run (node:internal/modules/esm/module_job:197:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:341:24)
    at async loadESM (node:internal/process/esm_loader:88:5)
    at async handleMainPromise (node:internal/modules/run_main:61:12)

Example 2

process.env.LANG = 'C';
console.log(new Date().toLocaleString());

node v14.17.6, v16.14.1:

node 18.0.0-pre:

2022-3-23 1:33:56 // LANG="jp" was defined in environment

How often does it reproduce? Is there a required condition?

Depends on Node version; maybe on system-icu, environment, etc.

What is the expected behavior?

Failed tests on deps bump, investigation, decision, solution.

What do you see instead?

Inconsistent behaviour in userland, weird and hard-to-debug bugs.

Additional information

I'm not 100% sure, but example 2 seems to be caused by internal caching in v8/icu. Basically it ignores setted values, such as process.env.{LANG,LC_ALL,LC_TIME}. Similar problem happened with TZ setter earlier; Node overrides it with #20026
No clue about example 1.
Not sure if any of these must be "fixed" in Node itself (i.e. as separate issues/PRs).

Both problems could have been catched by simple tests. Improving coverage would allow to prevent such problems in the future.

Note: if CI runs in some sort of default/canonical environments, it might be a good idea to make it possible to do multiple or random combinations somehow, especially for i18n-related parts.
There is a pretty common tendency between developers to set en_US.UTF-8 locale just to have more searchable and shareable outputs, so some bugs might slip off even from a huge multilingual community.