Skip to content

fix(duration): apply the leading sign when parsing a negative ISO duration#3147

Open
spokodev wants to merge 1 commit into
iamkun:devfrom
spokodev:fix/duration-negative-iso-parse
Open

fix(duration): apply the leading sign when parsing a negative ISO duration#3147
spokodev wants to merge 1 commit into
iamkun:devfrom
spokodev:fix/duration-negative-iso-parse

Conversation

@spokodev

Copy link
Copy Markdown

Problem

Parsing a negative ISO-8601 duration string drops the leading sign:

dayjs.duration('-P1Y').asYears()   // returns 1, expected -1
dayjs.duration('-P1DT2H').asHours() // returns 26, expected -26

The parser does d.slice(2) over the regex match and never reads the sign captured in d[1]. Because toISOString() correctly emits -P..., the round-trip invariant breaks:

const d = dayjs.duration(-1, 'years')
dayjs.duration(d.toISOString()).asMilliseconds() === d.asMilliseconds() // false before this fix

Refs #1516.

Fix

Derive a sign multiplier from d[1] === '-' and apply it to each parsed component, so the serialized output parses back to the original value.

Scope

Leading-sign case only. Per-component signs (e.g. P-6M3D) are a separate serializer limitation and are out of scope here.

Tests

Added a round-trip test covering asYears, asHours, toISOString, and the duration(d.toISOString()) === d invariant. Red before the fix, green after; duration suite 31/31, duration + relativeTime 40/40.

…ation

The ISO-8601 duration parser called d.slice(2) and never read the
sign captured in d[1], so a leading-minus string parsed as positive.
toISOString() correctly emits -P..., so the round-trip
duration(d.toISOString()) flipped the sign.

Derive a sign multiplier from d[1] === '-' and apply it to each
parsed component. Scope is the leading-sign case only; per-component
signs are a separate serializer limitation.

Refs iamkun#1516
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