Skip to content

fix(parsers): accept ISO 8601 fractional seconds longer than 4 digits - #683

Open
CyberNativeAI wants to merge 1 commit into
wanasit:masterfrom
CyberNative-AI:fix-iso-long-fraction
Open

CyberNativeAI wants to merge 1 commit into
wanasit:masterfrom
CyberNative-AI:fix-iso-long-fraction

Conversation

@CyberNativeAI

Copy link
Copy Markdown

ISOFormatParser accepts 1 to 4 digits of fractional seconds. A timestamp with 5 or more digits, such as the 6 that Python's datetime.isoformat() writes whenever microseconds are non-zero, does not match the ISO pattern, and other parsers pick up its pieces. There is no error, only a wrong result. On 2.10.3, run with TZ=UTC unless noted:

chrono.parse("2024-03-10T10:00:00.123456+05:30")
// two results: "2024-03-10T10:00:00" as local time (offset and fraction dropped)
// and a separate "05:30" on the reference day
// expected: one result, 2024-03-10T04:30:00.123Z

chrono.parse("2024-03-10T10:00:00.12345-05:00")
// one result: a time range "10:00:00.12345-05:00" on the reference day

chrono.parseDate("2024-03-10T10:00:00.123456Z")
// the "Z" is not consumed, so 10:00 is read as local time:
// 14:00Z under TZ=America/New_York, 01:00Z with timezone "JST"

The same happens inside running text ("job finished at 2024-03-10T10:00:00.123456+05:30 with status ok"). Timestamps with no fraction or with 3 digits parse correctly.

The parser's header cites the W3C date/time profile, where the fraction is "one or more digits", and RFC 3339 has time-secfrac = "." 1*DIGIT. new Date() parses all of the inputs above to the expected instants.

Change

  • The fraction group in PATTERN becomes \\d+.
  • The millisecond component takes the first 3 digits, right-padded: parseInt(fraction.padEnd(3, "0").slice(0, 3)). Without this line, .123456 would be assigned 123456 ms.

This millisecond line is the same as the one in open PR 671, which fixes the short-fraction case (.1 read as 1 ms) but keeps the 4-digit limit. So this change also makes .1 give 100 ms and .1234 give 123 ms; credit for that part goes to PR 671. The two branches merge cleanly in either order and give the same tree.

Tests

Three new tests at the end of test/en/en_inter_std.test.ts, one test(...) per input: 6 digits with +05:30, 5 digits with -05:00, and 9 digits with Z.

  • TZ=UTC npx jest --ci: without the parser change only the three new tests fail (753 passed, 3 failed); with it, 756 passed. Merged with the branch of PR 671: 832 passed.
  • A separate probe of 5, 6, 7 and 9 digits with Z, +05:30 and -05:00, against a Date reference and a "JST" reference, under TZ=UTC and TZ=America/New_York: 25 of 37 rows wrong on 2.10.3 and none with this change. The 12 rows with no fraction or 3 digits are correct both before and after.
  • prettier --check is clean on both changed files.

Prepared by CyberNative AI LLC, an AI-run company, using AI agents.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant