DateTime: toDate reads formatToParts by position, breaks on Hermes Android (no fractionalSecond part)
Maintainers usually reply within 1 day
@maricastroc is already working on this.
Since Oct 3, 2026.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 84/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- android, react-native, typescript
- Domain
- mobile-dev
Research direction
Start in internal/dateTime.ts at toDate, where the zone formatter's formatToParts output is read by position. Reproduce the failure with the supplied Node snippet, then verify that formatIsoDate returns the expected local date when fractionalSecond is absent, including on Hermes Android.
Written by the indexing model from the issue text.
Description
What version of Effect is running?
4.0.0 (also present on main)
What steps can reproduce the bug?
toDate in internal/dateTime.ts reads the zone formatter's formatToParts output by position: parts[0] is the month, parts[2] the year, through parts[6] for the fractional second. When the runtime's Intl leaves out a part, the indices shift and a later part, such as the time zone name, ends up in a numeric slot.
Hermes on Android does this. Its Java-backed Intl ignores fractionalSecondDigits, so no fractionalSecond part is emitted and parts[6] is the timeZoneName ("GMT+10:00"). Number("GMT+10:00") is NaN, the Date becomes invalid, and anything that formats it throws. In our React Native app, every DateTime.formatIsoDate on a zoned value threw on Android.
A Node repro that simulates the missing part:
import { DateTime } from "effect"
const formatToParts = Intl.DateTimeFormat.prototype.formatToParts
Intl.DateTimeFormat.prototype.formatToParts = function(date) {
return formatToParts.call(this, date).filter((part) => part.type !== "fractionalSecond")
}
const zoned = DateTime.makeZonedUnsafe(new Date(), { timeZone: DateTime.zoneMakeLocal() })
DateTime.formatIsoDate(zoned)
What is the expected behavior?
"2026-10-03", or whatever the local date is.
What do you see instead?
RangeError: Invalid time value in Node. Hermes reports the same failure as RangeError: Date value out of bounds.
Additional information
Reading the parts by type fixes it, and falling back to the epoch's own milliseconds when fractionalSecond is absent is exact for any zone with a whole-second offset:
const parts: Partial<Record<Intl.DateTimeFormatPartTypes, string>> = {}
for (const part of self.zone.format.formatToParts(self.epochMilliseconds)) {
parts[part.type] = part.value
}
const date = new Date(0)
date.setUTCFullYear(Number(parts.year), Number(parts.month) - 1, Number(parts.day))
date.setUTCHours(
Number(parts.hour),
Number(parts.minute),
Number(parts.second),
parts.fractionalSecond === undefined
? self.epochMilliseconds - Math.floor(self.epochMilliseconds / 1000) * 1000
: Number(parts.fractionalSecond)
)
Hermes's Android Intl: lib/Platform/Intl/java/com/facebook/hermes/intl in facebook/hermes has no fractionalSecondDigits handling.
- Dominant language
- TypeScript
- Stars
- 16.7k
- Forks
- 808
- Avg merge
- 10h 7m
- Merged PRs (30d)
- 441
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Effect-TS/effect
-
BrowserWorkerRunner: port finalizer throws when the worker global has no close() (Bun)Possibly taken @santiago-ramos-02 claimed this 5 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Effect-TS/effect#8635 · 3 comments ·
Maintainers usually reply within 1 day
-
3.0
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Effect-TS/effect#8424 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Effect-TS/effect#8101 · 1 comment ·
Maintainers usually reply within 1 day
-
3.0 bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Effect-TS/effect#6294 · 3 comments ·
Maintainers usually reply within 1 day
-
@effect/platform: HttpClientRequest emits explicit Content-Length, causing wire mismatches under undici 8.2+Possibly taken @sijie-Z claimed this 119 days ago. Open3.0 bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Effect-TS/effect#6240 · 2 comments ·
Maintainers usually reply within 1 day
All issues in Effect-TS/effect
Similar issues
-
bot:ai-assisted status:untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
midnightntwrk/midnight-js#1424 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
mksglu/context-mode#1268 ·
Maintainers usually reply within 5 days
-
Edit:Opencheck:failed streams:edit
Difficulty 2/5 1-3 hours Newbie friendliness 60/100
iptv-org/iptv#54352 · 1 comment ·
Maintainers usually reply within 1 day
-
[Table] reserveSelectedRowOnPaginate=false 时表头全选包含其他页数据Possibly taken @dvd233 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Tencent/tdesign-react#4416 · 2 comments ·
Maintainers usually reply within 1 day
-
area:widget bug
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
interledger/publisher-tools#894 ·
Maintainers usually reply within 1 day