fix(isISO8601): validate week dates in strict mode - #2869
Open
yfwmaniish wants to merge 2 commits into
Open
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2869 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 114 114
Lines 2599 2611 +12
Branches 658 661 +3
=========================================
+ Hits 2599 2611 +12 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
isValidDate() had no branch for week dates (YYYY-Www[-D]), so
isISO8601(str, { strict: true }) never actually validated them --
it fell through to the ordinal/calendar-date branch, which always
returned true for any string matching the loose /(\d{4})-?(\d{0,2})-?(\d*)/
capture (week strings capture only the year, since "Www" isn't digits).
The main iso8601 regex already constrains the week field to 01-53
syntactically, but only weeks 01-52 exist in every ISO week-numbering
year -- week 53 exists only in "long" years (53 ISO weeks). Added
hasISOWeek53() using the standard algorithm (move 31 Dec to the
Thursday of its own ISO week, compare that Thursday's year-relative
week number) and a weekMatch branch in isValidDate that applies it.
Fixes validatorjs#2859.
codecov flagged the strict week-date patch at 91.66% -- one of the three new branches was never taken. Two of the added lines short-circuit on data the existing cases never supply: - `week <= 52 || hasISOWeek53(year)` only ever evaluated the right-hand side, because every new case used week 53. Added '2020-W10' and '2020-W10-3'. - `dec31.getUTCDay() || 7` only remaps Sunday, and 31 December falls on a Sunday in none of the years tested so far. Added '2017-W53' -- 31 Dec 2017 is a Sunday and 2017 is a short year, so it exercises the remap and stays correctly invalid. isISO8601.js is now at 100% statement, branch, function and line coverage. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
yfwmaniish
force-pushed
the
fix/iso8601-strict-week53
branch
from
August 26, 2026 06:35
114df15 to
b8035a9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
isISO8601(str, { strict: true })never actually validates week dates (YYYY-Www/YYYY-Www-D).isValidDate()has no branch for them, so a week-date string falls through to the ordinal/calendar-date branch:Against
"2019-W53", this loose regex only captures the year ("W53"isn't digits, somonth/daycapture empty strings →NaNafterNumber()). Withmonth/dayfalsy, the function skips the date-object comparison entirely and returnstrueunconditionally:So every syntactically-valid week-date string passes strict mode regardless of whether the year actually has that many weeks. The main
iso8601regex already constrains the week field to01-53syntactically, but only weeks 01-52 exist in every ISO week-numbering year — week 53 exists only in "long" years (years whose 31 December falls in week 53 rather than week 1 of the next year).2019-W53-1, for example, is not a real date, but strict mode accepts it today.Fix
Added
hasISOWeek53(year), using the standard ISO week-number algorithm (move 31 December to the Thursday of its own ISO week, then compare that Thursday's year-relative week number), and aweekMatchbranch inisValidDatethat applies it:Testing
'should validate ISO 8601 dates, with strict = true'test block: 4 valid (2015-W53-1,2015-W53,2020-W53-7,2026-W53— all real long years) and 4 invalid (2019-W53-1,2019-W53,2021-W53-7,2022-W53— all real short years, so week 53 doesn't exist).isISO8601.jsfix (kept the new tests) and reran — thestrict = trueblock fails exactly as expected, on the first new invalid case (isISO8601("2019-W53-1", {strict:true})passed but should have failed). Restored the fix and reran clean.npm run build && npm run lint && mocha— 292/292 passing, lint clean.Fixes #2859.
Related-but-separate issues in the same cluster (not addressed by this PR):
isISO8601misroutes signed ordinal dates #2860,isISO8601accepts any whitespace as the date-time separator #2861 already have open PRs (fix(isISO8601): validate signed ordinal dates in strict mode #2865, fix(isISO8601): reject whitespace other than space as date-time separator #2864 respectively).isISO8601rejectsT24:00:00and accepts mixed separators #2858 (T24:00 separator capture-group issue) needs capture-group renumbering across a regex shared withiso8601StrictSeparator— left alone as too risky to fix without dedicated attention.isFloatbuilds a literalundefinedseparator for an unknown locale #2862,isRFC3339accepts leap seconds at impossible instants #2863 not investigated as part of this PR.