From c102f2186e96bb4e74540bfc372d270de1c0dd55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C5=8Dan?= Date: Tue, 5 May 2026 04:04:19 -0600 Subject: [PATCH] fix: Date::Language::str2time ignores EPOCH reference parameter Date::Parse::str2time accepts an optional third argument (EPOCH) used as the reference time when inferring missing date components. The equivalent method in Date::Language silently discarded this parameter, always using time() as the reference. This caused inconsistent behavior: parsing "25 Dec" with a July 2024 reference returned Dec 2023 via Date::Parse but Dec 2025 (current year minus one) via Date::Language. Fix: extract the EPOCH parameter before calling strptime, matching the Date::Parse implementation pattern. Co-Authored-By: Claude Opus 4.6 --- lib/Date/Language.pm | 3 ++- t/lang-str2time.t | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/Date/Language.pm b/lib/Date/Language.pm index 17570f4..ae7e101 100644 --- a/lib/Date/Language.pm +++ b/lib/Date/Language.pm @@ -74,13 +74,14 @@ sub format_Z { sub str2time { my $me = shift; + my $now = @_ > 2 ? splice(@_, 2, 1) : time; my @t = $me->strptime(@_); return undef unless @t; my($ss,$mm,$hh,$day,$month,$year,$zone) = @t; - my @lt = localtime(time); + my @lt = localtime($now); $hh ||= 0; $mm ||= 0; diff --git a/t/lang-str2time.t b/t/lang-str2time.t index 658ed48..78f7c1a 100644 --- a/t/lang-str2time.t +++ b/t/lang-str2time.t @@ -105,4 +105,45 @@ my $lang = Date::Language->new('English'); is($parsed, $t, "German round-trip ctime/str2time"); } +# --- EPOCH parameter: Date::Language should match Date::Parse --- + +{ + # Use a fixed reference time: July 1 2024 00:00:00 UTC + my $ref = 1719792000; + + # "25 Dec" relative to July 2024 → Dec 2023 (most recent past) + my $dp = str2time("25 Dec", undef, $ref); + my $dl = $lang->str2time("25 Dec", undef, $ref); + + ok(defined $dp, "Date::Parse parses '25 Dec' with EPOCH ref"); + ok(defined $dl, "Date::Language parses '25 Dec' with EPOCH ref"); + + if (defined $dp && defined $dl) { + my @dp_t = gmtime($dp); + my @dl_t = gmtime($dl); + is($dl_t[5] + 1900, $dp_t[5] + 1900, + "EPOCH param: '25 Dec' ref=Jul-2024 → year matches Date::Parse (" + . ($dp_t[5] + 1900) . ")"); + is($dl_t[5] + 1900, 2023, + "EPOCH param: '25 Dec' ref=Jul-2024 → year 2023 (most recent past)"); + } + + # "15 Mar" relative to July 2024 → Mar 2024 (already past this year) + my $dp2 = str2time("15 Mar", undef, $ref); + my $dl2 = $lang->str2time("15 Mar", undef, $ref); + + ok(defined $dp2, "Date::Parse parses '15 Mar' with EPOCH ref"); + ok(defined $dl2, "Date::Language parses '15 Mar' with EPOCH ref"); + + if (defined $dp2 && defined $dl2) { + my @dp_t = gmtime($dp2); + my @dl_t = gmtime($dl2); + is($dl_t[5] + 1900, $dp_t[5] + 1900, + "EPOCH param: '15 Mar' ref=Jul-2024 → year matches Date::Parse (" + . ($dp_t[5] + 1900) . ")"); + is($dl_t[5] + 1900, 2024, + "EPOCH param: '15 Mar' ref=Jul-2024 → year 2024 (past this year)"); + } +} + done_testing;