Fix ISO8601 parsing with explicit languages - #1352
Merged
serhii73 merged 1 commit intoJul 23, 2026
Merged
Conversation
AdrianAtZyte
approved these changes
Jul 22, 2026
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1352 +/- ##
=======================================
Coverage 97.12% 97.13%
=======================================
Files 235 235
Lines 2924 2927 +3
=======================================
+ Hits 2840 2843 +3
Misses 84 84 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
Fixes #360
Bug
dateparser.parse("2017-06-22", languages=["it"])returnsNone, while the same string parses fine withlanguages=["en"]or with nolanguagesat all.There is also a silent variant: when the day is ≤ 12, a wrong date is returned instead of
None:Any language whose locale date order is day-first is affected (
it,fr,de, …) — 253 of the 308 locales in the project data useDMY.Root cause
Italian's locale
date_orderisDMY, so_parser'sparse_number()indateparser/parser.pytries to assign numeric tokens to components in day → month → year order:2017only fitsyear(and, being a four-digit token, also setsskip_component = "year"for the remaining tokens),06is assigned to day, because day precedes month inDMY,22cannot be a month (> 12) and the year slot is skipped, so assignment fails withValueError: Unable to parse: 22, and the result isNone.For
2017-06-10the last token can be a month, so parsing "succeeds" — with month and day swapped.Fix
A date string that starts with a four-digit year is big-endian (ISO 8601-style); no real-world notation puts the day between the year and the month (no locale in the project data uses
YDM). So, when the year has already been consumed from a leading four-digit token and neither day nor month has been assigned yet,parse_number()now expects the remaining numeric components in month → day order.The correction deliberately does not apply when the caller explicitly sets
DATE_ORDER(checked viasettings._mod_settings, the same mechanismdate.pyuses to decide whether the locale order applies), so explicitDATE_ORDER="DMY"/"YDM"behavior is unchanged. It also does not trigger for strings where the year is not the leading token (22-06-2017,06 2017 10) or for two-digit years, and the existingPREFER_LOCALE_DATE_ORDER=Falseworkaround keeps working.Tests
Added
test_iso_datestamp_format_should_parse_with_locale_date_ordercovering:2017-06-22,it— wasNone),2017-06-10,it— was October 6),2017-06-22,fr),PREFER_LOCALE_DATE_ORDER=Falseworkaround that the neighbouring existing test needs.All four fail on current master and pass with the fix. Full suite: 24064 passed, 20 skipped, 1 xfailed.
pre-commit(ruff, ruff-format) passes.Related: #790 proposes a dedicated ISO parser; this PR instead makes a minimal correction to the existing token-assignment logic, which also fixes the silent month/day swap that occurs before any fallback parser would run.