Environment
Android 15 / API 35 emulator, React Native 0.86.3, Hermes 250829098.0.17. Compared in the same app against Android Chromium WebView 124. Reproducer: https://github.com/mozzius/hermes-datetimeformat-repro (native Hermes and WebView side by side).
Minimal repro
const midnight = new Date('2026-05-28T21:54:00Z') // 00:54 in Europe/Helsinki
for (const [locale, hourCycle] of [
['en-GB', 'h11'],
['en-US', 'h24'],
]) {
const formatter = new Intl.DateTimeFormat(locale, {
timeStyle: 'short',
hourCycle,
timeZone: 'Europe/Helsinki',
})
console.log(locale, formatter.format(midnight), formatter.resolvedOptions().hourCycle)
}
| Request |
Android Hermes |
Chromium WebView |
en-GB, explicit h11 |
12:54 am, reports h11 |
00:54 am, reports h11 |
en-US, explicit h24 |
00:54, reports h24 |
24:54, reports h24 |
The day-period spacing varies by engine, but the hour at midnight is the issue: h11 must start at 0 and h24 at 24. Hermes returns the opposite cycle's hour despite reporting the requested cycle. This also affects hour12 selection: en-GB + hour12: true resolves to h11 while formatting midnight as 12:54 am; en-US + hour12: false resolves to h24 while formatting 00:54.
Source observations
lib/Platform/Intl/java/com/facebook/hermes/intl/DateTimeFormat.java pairs a default h23 with h11 and h12 with h24 for hour12, rather than selecting the locale's preferred 12-/24-hour cycle.
PlatformDateTimeFormatterICU.java maps both H11 and H12 to an h skeleton and both H23 and H24 to a k skeleton. The API 35 formatter subsequently formats 12 or 00 in the explicit midnight cases above.
- The Android Test262 harness skips
DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js.
This is distinct from the Apple backend's ignored styled hour12 request in #2208. Android does honor that request and formats the Bluesky case as a 12-hour time; its incorrect midnight semantics need an Android-specific fix and regression tests. I have not tested pre-API-24 Android's separate java.text implementation.
Environment
Android 15 / API 35 emulator, React Native 0.86.3, Hermes
250829098.0.17. Compared in the same app against Android Chromium WebView 124. Reproducer: https://github.com/mozzius/hermes-datetimeformat-repro (native Hermes and WebView side by side).Minimal repro
en-GB, explicith1112:54 am, reportsh1100:54 am, reportsh11en-US, explicith2400:54, reportsh2424:54, reportsh24The day-period spacing varies by engine, but the hour at midnight is the issue:
h11must start at 0 andh24at 24. Hermes returns the opposite cycle's hour despite reporting the requested cycle. This also affectshour12selection:en-GB+hour12: trueresolves toh11while formatting midnight as12:54 am;en-US+hour12: falseresolves toh24while formatting00:54.Source observations
lib/Platform/Intl/java/com/facebook/hermes/intl/DateTimeFormat.javapairs a defaulth23withh11andh12withh24forhour12, rather than selecting the locale's preferred 12-/24-hour cycle.PlatformDateTimeFormatterICU.javamaps bothH11andH12to anhskeleton and bothH23andH24to akskeleton. The API 35 formatter subsequently formats12or00in the explicit midnight cases above.DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js.This is distinct from the Apple backend's ignored styled
hour12request in #2208. Android does honor that request and formats the Bluesky case as a 12-hour time; its incorrect midnight semantics need an Android-specific fix and regression tests. I have not tested pre-API-24 Android's separatejava.textimplementation.