From 12ffc09458f3b6c4bc1b69a1688d7db8806761d2 Mon Sep 17 00:00:00 2001 From: "carpentry-heartbeat[bot]" Date: Sat, 15 Aug 2026 00:26:48 +0200 Subject: [PATCH] Don't apply the am/pm shift to an unparsed hour in strptime The hour accumulator starts at the sentinel -1, and the am/pm adjustment ran before that sentinel was checked. For a format with %p but no %H or %I, PM took the (< hr 12) branch and turned -1 into 11, so the sentinel check on the next line no longer matched and the caller was handed a fabricated 11:00 instead of Nothing: (Datetime.strptime "PM 2024-03-15" "%p %Y-%m-%d") -> hours = (Just 11) AM was unaffected, since (= hr 12) is false for -1. Skip the adjustment when the hour was never parsed, so hours comes back as Nothing like every other unparsed field in that same let. --- test/time.carp | 25 +++++++++++++++++++++++++ time.carp | 1 + 2 files changed, 26 insertions(+) diff --git a/test/time.carp b/test/time.carp index a3421ed..aa0b114 100644 --- a/test/time.carp +++ b/test/time.carp @@ -1152,6 +1152,31 @@ (Result.Error _) -2) "strptime %I %p parses 12 PM as 12") + (assert-equal test + -1 + (match (Datetime.strptime "PM 2024-03-15" "%p %Y-%m-%d") + (Result.Success dt) (Maybe.from @(Datetime.hours &dt) -1) + (Result.Error _) -2) + "strptime %p with no hour specifier leaves the hour unset (PM)") + (assert-equal test + -1 + (match (Datetime.strptime "AM 2024-03-15" "%p %Y-%m-%d") + (Result.Success dt) (Maybe.from @(Datetime.hours &dt) -1) + (Result.Error _) -2) + "strptime %p with no hour specifier leaves the hour unset (AM)") + (assert-equal test + 15 + (match (Datetime.strptime "03 PM 2024-03-15" "%I %p %Y-%m-%d") + (Result.Success dt) (Maybe.from @(Datetime.hours &dt) -1) + (Result.Error _) -2) + "strptime %I %p parses 03 PM as 15") + (assert-equal test + 7 + (match (Datetime.strptime "07 2024-03-15" "%H %Y-%m-%d") + (Result.Success dt) (Maybe.from @(Datetime.hours &dt) -1) + (Result.Error _) -2) + "strptime %H parses the hour with no am/pm marker") + (assert-equal test 123456789 (match (Datetime.strptime "14:30:00.123456789" "%H:%M:%S.%n") diff --git a/time.carp b/time.carp index 448b8f5..cf44762 100644 --- a/time.carp +++ b/time.carp @@ -1090,6 +1090,7 @@ Example: (Result.Error e) (Result.Error e) (Result.Success d) (let [final-hr (cond + (= hr -1) hr (= ampm 2) (if (< hr 12) (+ hr 12) hr) (= ampm 1) (if (= hr 12) 0 hr) hr)