Skip to content

fix(plugin): parse timezone offset in customParseFormat strict mode - #3182

Open
stevechen256-source wants to merge 1 commit into
iamkun:devfrom
stevechen256-source:fix/customParseFormat-strict-timezone
Open

fix(plugin): parse timezone offset in customParseFormat strict mode#3182
stevechen256-source wants to merge 1 commit into
iamkun:devfrom
stevechen256-source:fix/customParseFormat-strict-timezone

Conversation

@stevechen256-source

Copy link
Copy Markdown

What & Why

customParseFormat strict mode rejects valid date strings that contain a timezone offset (Z/ZZ token) whenever the input offset differs from the local timezone. For example, on a non-UTC machine:

dayjs('2024-08-19T10:30:00Z', 'YYYY-MM-DDTHH:mm:ssZ', true).isValid()
// => false  (expected: true)

The root cause is the strict-mode round-trip check (date != this.format(format)): format() renders a Z/ZZ token using the local timezone offset, so the reformatted string legitimately differs from the input (both the offset lexeme and the wall-clock fields), and the input is wrongly discarded.

This has been reported several times: #2712, #2730, #2741, #2607.

Changes

  • parseFormattedInput now also returns the parsed timezone offset.
  • When the format contains a timezone token, the strict check re-renders the parsed instant in the input's own offset (equivalent to rendering it in UTC) and normalizes the input's offset lexeme (Z, +09, +09:00, +0900, …) to the corresponding UTC form before comparing. This keeps the existing round-trip semantics (padding, literal characters, out-of-range dates such as 2024-02-31 are still rejected) while making offsets round-trip correctly.
  • Added regression tests covering ISO 8601 Z, offsets like +09/+00:00, Z against a ZZ token, and the invalid 2024-02-31 case.

Test plan

  • npm test passes: 4 timezone passes of timezone.test (6/6 each), 4 timezone-plugin passes (54/54 each), full suite 799 passed, 799 total with the repo's 100% line-coverage threshold.
  • Verified in multiple TZ values (UTC, Asia/Shanghai, America/New_York, Europe/Paris, Pacific/Auckland): parsed valueOf() matches moment exactly for all new cases, and out-of-range dates stay invalid.
  • eslint clean on the changed files.

When parsing with the customParseFormat plugin in strict mode, the round-trip
comparison reformats the parsed date using the local timezone offset, so a
valid input whose offset differs from the local one (e.g. an ISO 8601 'Z'
string parsed in a non-UTC timezone) was always rejected as invalid.

Compare the input against the reformatted output in the input's own offset
(equivalent to rendering it in UTC) whenever a Z/ZZ token was parsed, so
offsets round-trip correctly while out-of-range dates are still rejected.
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