From b4934c91b557349615e119535ec55cb662c2189c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C5=8Dan?= Date: Sun, 3 May 2026 06:21:05 -0600 Subject: [PATCH] fix: DD-MM-YYYY swap off-by-one for day 13 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The date swap logic uses 0-indexed months ($month = $1 - 1) but checked $month > 12 instead of $month > 11. This meant that when the first field was exactly 13, $month was 12 (one past December), which did NOT trigger the swap — so "13-01-2025" was parsed as invalid month 12 instead of January 13. Fix: change the boundary check from $month > 12 to $month > 11, so any value that cannot be a valid month (0-11) triggers the DD-MM-YYYY or YYYY-MM-DD disambiguation. Co-Authored-By: Claude Opus 4.6 --- lib/Date/Parse.pm | 2 +- t/ddmmyyyy.t | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/Date/Parse.pm b/lib/Date/Parse.pm index fd6cef2..0a2f614 100644 --- a/lib/Date/Parse.pm +++ b/lib/Date/Parse.pm @@ -162,7 +162,7 @@ sub { if ($5) { $year = $5; # Possible match for 1995-01-24 or 31-12-2023 - if ($month > 12) { + if ($month > 11) { if ($1 > 31) { # YYYY-MM-DD (mainframe date format) ($year,$month,$day) = ($1, $3 - 1, $5); diff --git a/t/ddmmyyyy.t b/t/ddmmyyyy.t index 726019c..f778407 100644 --- a/t/ddmmyyyy.t +++ b/t/ddmmyyyy.t @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 12; +use Test::More tests => 18; use Date::Parse qw(strptime str2time); # DD-MM-YYYY (European date format) — the first field exceeds 12, @@ -33,3 +33,18 @@ is($r[4], 11, "31-12-96: month = 11 (December, 0-based)"); is($r[3], 24, "1995-01-24: day = 24"); is($r[4], 0, "1995-01-24: month = 0 (January, 0-based)"); is($r[5], 95, "1995-01-24: year = 95 (1995 - 1900)"); + +# 13-01-2025 → 13 Jan 2025 +# Regression: first field = 13 produces $month = 12 (0-indexed), +# which is > 11 but was NOT > 12 in the old check, so the swap +# from MM-DD to DD-MM never triggered. +@r = strptime("13-01-2025"); +is($r[3], 13, "13-01-2025: day = 13 (not treated as month)"); +is($r[4], 0, "13-01-2025: month = 0 (January, 0-based)"); +is($r[5], 125, "13-01-2025: year = 125 (2025 - 1900)"); +ok(defined str2time("13-01-2025"), "str2time('13-01-2025') is defined"); + +# 14-02-2025 → 14 Feb 2025 (also affected by off-by-one) +@r = strptime("14-02-2025"); +is($r[3], 14, "14-02-2025: day = 14"); +is($r[4], 1, "14-02-2025: month = 1 (February, 0-based)");