Bug Description
Intl.NumberFormat with style: 'unit' returns the wrong unit for duration-style units in Hermes. In particular, hour and minute are formatted as seconds, and day is formatted with the singular unit in en-US even for plural values.
This caused a React Native app countdown that should render as 23 days 22 hr to render as 23 day 79,200s on Hermes.
I searched existing Intl.NumberFormat issues and found related NumberFormat correctness issues such as #1035 and #1318, but I did not find an exact duplicate for style: 'unit' with day / hour / minute.
Hermes git revision (if applicable): hermes-v0.16.0 release tarball; also observed with hermes-v0.14.1
React Native version: 0.85.3 for the latest-version check; originally observed in 0.83.4
OS: macOS 26.4.1 (arm64), iOS React Native app runtime
Platform (most likely one of arm64-v8a, armeabi-v7a, x86, x86_64): arm64 / iOS + macOS Hermes CLI from the iOS prebuilt tarball
Steps To Reproduce
- Install or download Hermes
0.16.0 from the React Native 0.85.3 Hermes iOS prebuilt artifact.
- Run the code below with the Hermes CLI from that artifact.
- Compare the output with JavaScriptCore or Node/V8.
Commands used for the latest React Native / Hermes check:
mkdir -p /tmp/hermes-rn-latest-check
cd /tmp/hermes-rn-latest-check
bun init -y
bun add react-native@0.85.3
curl -L \
https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/0.16.0/hermes-ios-0.16.0-hermes-ios-debug.tar.gz \
-o hermes-ios-debug.tar.gz
mkdir hermes-016
tar -xzf hermes-ios-debug.tar.gz -C hermes-016
./hermes-016/destroot/bin/hermes repro.js
Code example (repro.js):
const log = typeof print === 'function' ? print : console.log;
function show(unit, value) {
const formatted = new Intl.NumberFormat('en-US', {
style: 'unit',
unit,
unitDisplay: 'short',
maximumFractionDigits: 1,
}).format(value);
log(`${unit}: ${formatted}`);
}
show('day', 2);
show('hour', 2);
show('minute', 2);
show('second', 2);
Hermes 0.16.0 output:
day: 2 day
hour: 7,200s
minute: 120s
second: 2s
Hermes version output:
Hermes JavaScript compiler and Virtual Machine.
Hermes release version: 0.16.0
HBC bytecode version: 96
JavaScriptCore on the same machine, using osascript -l JavaScript, returns:
day: 2 days
hour: 2 hr
minute: 2 min
second: 2 sec
Node/V8 on the same machine returns:
day: 2 days
hour: 2 hr
minute: 2 min
second: 2 sec
The same Hermes behavior also reproduces with my app's installed Hermes 0.14.1 from React Native 0.83.4:
Hermes release version: 0.14.1
HBC bytecode version: 96
day: 2 day
hour: 7,200s
minute: 120s
second: 2s
The Expected Behavior
Intl.NumberFormat should preserve the requested unit when style: 'unit' is used.
Expected en-US short-unit output for the example above:
day: 2 days
hour: 2 hr
minute: 2 min
second: 2 sec
At minimum, unit: 'hour' should not format the value as seconds (2 hr should not become 7,200s), and unit: 'minute' should not become seconds (2 min should not become 120s).
Bug Description
Intl.NumberFormatwithstyle: 'unit'returns the wrong unit for duration-style units in Hermes. In particular,hourandminuteare formatted as seconds, anddayis formatted with the singular unit inen-USeven for plural values.This caused a React Native app countdown that should render as
23 days 22 hrto render as23 day 79,200son Hermes.I searched existing
Intl.NumberFormatissues and found related NumberFormat correctness issues such as #1035 and #1318, but I did not find an exact duplicate forstyle: 'unit'withday/hour/minute.gradle cleanand confirmed this bug does not occur with JSC. N/A for this report: the repro below is iOS/macOS Hermes CLI. I did compare against JavaScriptCore on macOS and V8/Node; both return the expected unit strings.0.16.0iOS prebuilt tarball referenced byreact-native@0.85.3when Hermes V1 is disabled. The same issue also reproduces in my app on React Native0.83.4/ Hermes0.14.1.Hermes git revision (if applicable):
hermes-v0.16.0release tarball; also observed withhermes-v0.14.1React Native version:
0.85.3for the latest-version check; originally observed in0.83.4OS: macOS 26.4.1 (
arm64), iOS React Native app runtimePlatform (most likely one of arm64-v8a, armeabi-v7a, x86, x86_64):
arm64/ iOS + macOS Hermes CLI from the iOS prebuilt tarballSteps To Reproduce
0.16.0from the React Native0.85.3Hermes iOS prebuilt artifact.Commands used for the latest React Native / Hermes check:
mkdir -p /tmp/hermes-rn-latest-check cd /tmp/hermes-rn-latest-check bun init -y bun add react-native@0.85.3 curl -L \ https://repo1.maven.org/maven2/com/facebook/hermes/hermes-ios/0.16.0/hermes-ios-0.16.0-hermes-ios-debug.tar.gz \ -o hermes-ios-debug.tar.gz mkdir hermes-016 tar -xzf hermes-ios-debug.tar.gz -C hermes-016 ./hermes-016/destroot/bin/hermes repro.jsCode example (
repro.js):Hermes
0.16.0output:Hermes version output:
JavaScriptCore on the same machine, using
osascript -l JavaScript, returns:Node/V8 on the same machine returns:
The same Hermes behavior also reproduces with my app's installed Hermes
0.14.1from React Native0.83.4:The Expected Behavior
Intl.NumberFormatshould preserve the requested unit whenstyle: 'unit'is used.Expected
en-USshort-unit output for the example above:At minimum,
unit: 'hour'should not format the value as seconds (2 hrshould not become7,200s), andunit: 'minute'should not become seconds (2 minshould not become120s).