On 2025-06-08 17:39, Collin Funk wrote:
Posting on bug-gnulib since this test failure seems to be caused by
parse-datetime despite being caught by tests/date/date-debug.sh in
Coreutils.

I installed the attached patch to Gnulib, along with a minor testcase patch in Coreutils. Please give it a try.
From 7424e3cfaa7d4380e3c3a8658dc693579ffb1ff5 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sun, 8 Jun 2025 23:51:25 -0700
Subject: [PATCH] parse-datetime: debug mktime failures better
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lib/parse-datetime.y (debug_mktime_not_ok):
Handle mktime failures too.
Don’t pretend that the time was normalized if mktime failed.
Don’t attempt to deduce DST shifts; it’s impractical in general
and even a reasonable heuristic is too painful.
---
 ChangeLog            |  9 +++++++
 lib/parse-datetime.y | 57 +++++++++++++++++---------------------------
 2 files changed, 31 insertions(+), 35 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ef6c6d19be..c0eed85a66 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2025-06-08  Paul Eggert  <egg...@cs.ucla.edu>
+
+	parse-datetime: debug mktime failures better
+	* lib/parse-datetime.y (debug_mktime_not_ok):
+	Handle mktime failures too.
+	Don’t pretend that the time was normalized if mktime failed.
+	Don’t attempt to deduce DST shifts; it’s impractical in general
+	and even a reasonable heuristic is too painful.
+
 2025-06-07  Bruno Haible  <br...@clisp.org>
 
 	stdcountof-h: Work around a clang bug.
diff --git a/lib/parse-datetime.y b/lib/parse-datetime.y
index 9ffd0993a6..c120eae04a 100644
--- a/lib/parse-datetime.y
+++ b/lib/parse-datetime.y
@@ -1686,18 +1686,7 @@ static void
 debug_mktime_not_ok (struct tm const *tm0, struct tm const *tm1,
                      parser_control const *pc, bool time_zone_seen)
 {
-  /* TODO: handle t == -1 (as in 'mktime_ok').  */
   char tmp[DBGBUFSIZE];
-  int i;
-  const bool eq_sec   = (tm0->tm_sec  == tm1->tm_sec);
-  const bool eq_min   = (tm0->tm_min  == tm1->tm_min);
-  const bool eq_hour  = (tm0->tm_hour == tm1->tm_hour);
-  const bool eq_mday  = (tm0->tm_mday == tm1->tm_mday);
-  const bool eq_month = (tm0->tm_mon  == tm1->tm_mon);
-  const bool eq_year  = (tm0->tm_year == tm1->tm_year);
-
-  const bool dst_shift = eq_sec && eq_min && !eq_hour
-                         && eq_mday && eq_month && eq_year;
 
   if (!debugging (pc))
     return;
@@ -1705,35 +1694,33 @@ debug_mktime_not_ok (struct tm const *tm0, struct tm const *tm1,
   dbg_fputs (_("error: invalid date/time value:\n"));
   dbg_printf (_("    user provided time: '%s'\n"),
               debug_strfdatetime (tm0, pc, tmp, sizeof tmp));
-  dbg_printf (_("       normalized time: '%s'\n"),
-              debug_strfdatetime (tm1, pc, tmp, sizeof tmp));
-  /* The format must be aligned with debug_strfdatetime and the two
-     DEBUG statements above.  This string is not translated.  */
-  i = snprintf (tmp, sizeof tmp,
-                "                                 %4s %2s %2s %2s %2s %2s",
-                eq_year ? "" : "----",
-                eq_month ? "" : "--",
-                eq_mday ? "" : "--",
-                eq_hour ? "" : "--",
-                eq_min ? "" : "--",
-                eq_sec ? "" : "--");
-  /* Trim trailing whitespace.  */
-  if (0 <= i)
+  bool mktime_failed = tm1->tm_wday < 0;
+  if (mktime_failed)
+    dbg_fputs (_("    time could not be normalized\n"));
+  else
     {
-      if (sizeof tmp - 1 < i)
-        i = sizeof tmp - 1;
+      dbg_printf (_("       normalized time: '%s'\n"),
+                  debug_strfdatetime (tm1, pc, tmp, sizeof tmp));
+      /* The format must be aligned with debug_strfdatetime and the
+         dbg_printf statements above.  This string is not translated.  */
+      int i = sprintf (tmp, "%37s %2s %2s %2s %2s %2s",
+                       tm0->tm_year == tm1->tm_year ? "" : "----",
+                       tm0->tm_mon  == tm1->tm_mon  ? "" : "--",
+                       tm0->tm_mday == tm1->tm_mday ? "" : "--",
+                       tm0->tm_hour == tm1->tm_hour ? "" : "--",
+                       tm0->tm_min  == tm1->tm_min  ? "" : "--",
+                       tm0->tm_sec  == tm1->tm_sec  ? "" : "--");
+      /* Trim trailing whitespace.  */
       while (0 < i && tmp[i - 1] == ' ')
-        --i;
-      tmp[i] = '\0';
+        i--;
+      dbg_printf ("%.*s\n", i, tmp);
     }
-  dbg_printf ("%s\n", tmp);
 
   dbg_fputs (_("     possible reasons:\n"));
-  if (dst_shift)
-    dbg_fputs (_("       nonexistent due to daylight-saving time;\n"));
-  if (!eq_mday && !eq_month)
-    dbg_fputs (_("       invalid day/month combination;\n"));
-  dbg_fputs (_("       numeric values overflow;\n"));
+  dbg_fputs (_("       nonexistent due to daylight-saving time;\n"));
+  dbg_fputs (_("       invalid day/month combination;\n"));
+  if (mktime_failed)
+    dbg_fputs (_("       numeric values overflow;\n"));
   dbg_printf ("       %s\n", (time_zone_seen ? _("incorrect timezone")
                               : _("missing timezone")));
 }
-- 
2.48.1

Reply via email to