Skip to content

fix(customParseFormat): match MMM/MMMM against locale month names - #3157

Open
xianjianlf2 wants to merge 1 commit into
iamkun:devfrom
xianjianlf2:fix/customparseformat-dot-month-separator-2818
Open

fix(customParseFormat): match MMM/MMMM against locale month names#3157
xianjianlf2 wants to merge 1 commit into
iamkun:devfrom
xianjianlf2:fix/customparseformat-dot-month-separator-2818

Conversation

@xianjianlf2

Copy link
Copy Markdown

Problem

When parsing with customParseFormat, the generic "word" regex used for the MMM/MMMM month-name tokens excludes the -_:/,() separators and whitespace, but not .. As a result, an input like dayjs('29.Jul.2021', 'DD.MMM.YYYY') caused the month token to greedily capture Jul. (swallowing the trailing separator dot), which matches no month name and produced an Invalid Date. This is a regression from older versions and a divergence from moment, which parses the same input correctly.

Fix

Rather than naively adding . to the exclusion list (which would break locales whose short month names legitimately contain a dot, e.g. gl's xan.), MMM/MMMM now match against the actual locale month names, sorted longest-first. Because the captured value is now exactly one of the real month names, it can no longer swallow a trailing separator, while dotted month names continue to parse correctly.

Changes in src/plugin/customParseFormat/index.js:

  • Added an escapeRegExp helper.
  • Added matchMonthName(token) which builds a regex from the active locale's months (for MMMM) or monthsShort (for MMM, falling back to the first 3 chars of months), escaped and joined longest-first.
  • The parser now uses this month-name regex for the MMM/MMMM tokens instead of the generic word regex.

Testing

Added tests in test/plugin/customParseFormat.test.js:

  • 29.Jul.2021 with DD.MMM.YYYY parses to 2021-07-29 and matches moment.
  • 29.July.2021 with DD.MMMM.YYYY parses to 2021-07-29 and matches moment.
  • gl locale short month containing a dot (xan.) parses correctly with both dot and space separators (29.xan..2021 / 29 xan. 20212021-01-29).

Closes #2818

The generic `matchWord` regex used for the MMM/MMMM tokens excludes the
`-_:/,()` separators and whitespace, but not `.`. So parsing an input
such as `dayjs('29.Jul.2021', 'DD.MMM.YYYY')` made the month token greedily
capture `Jul.` (including the following separator dot), which matches no
month name and produced an Invalid Date — a regression from older versions
and a divergence from moment, which parses it correctly.

Rather than blindly adding `.` to the exclusion list (which would break
locales whose short month names legitimately contain a dot, e.g. `gl`'s
`xan.`), MMM/MMMM now match against the actual locale month names
(longest first). The captured value is therefore exactly the month name,
so it no longer swallows a trailing separator, while dotted month names
keep working.

Closes iamkun#2818
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.

Parse error with DD.MMM.YY format

1 participant