GNU bug report logs - #18328
date: '8pm -0500' is invalid (am/pm problem)

Previous Next

Package: coreutils;

Reported by: 積丹尼 Dan Jacobson <jidanni <at> jidanni.org>

Date: Mon, 25 Aug 2014 16:02:01 UTC

Severity: normal

Tags: confirmed

Full log


Message #18 received at 18328 <at> debbugs.gnu.org (full text, mbox):

From: Jeffery Palm <palmje <at> gmail.com>
To: 18328 <at> debbugs.gnu.org
Subject: Re: bug#18328: can't say date -d '8pm -0500' though other combos work
Date: Mon, 28 Jul 2025 22:02:30 -0700
[Message part 1 (text/plain, inline)]
I took a look at this bug, and believe I have a patch that will resolve it.

$ ../src/date --debug -d '2024-01-01 8:00:00PM -0500'
date: parsed date part: (Y-M-D) 2024-01-01
date: parsed time part: 08:00:00pm UTC-05
date: input timezone: parsed date/time string (-05)
date: using specified time as starting value: '20:00:00'
date: starting date/time: '(Y-M-D) 2024-01-01 20:00:00 TZ=-05'
date: '(Y-M-D) 2024-01-01 20:00:00 TZ=-05' = 1704157200 epoch-seconds
date: timezone: system default
date: final: 1704157200.000000000 (epoch-seconds)
date: final: (Y-M-D) 2024-01-02 01:00:00 (UTC)
date: final: (Y-M-D) 2024-01-01 17:00:00 (UTC-08)
date: output format: ‘%a %d %b %Y %T %Z’
Mon 01 Jan 2024 17:00:00 PST


And I was able to run the coreutils testsuite with no tests failing:

============================================================================
Testsuite summary for GNU coreutils 9.7.174-083f8
============================================================================
# TOTAL: 533
# PASS:  476
# SKIP:  57
# XFAIL: 0
# FAIL:  0
# XPASS: 0
# ERROR: 0
============================================================================

Are there any other tests/changes I should consider for this?


Below is the patch for the changes I made for this, including a new
testcase for AM/PM with timezone.


--- a/lib/parse-datetime.y
+++ b/lib/parse-datetime.y
@@ -592,7 +592,7 @@ debug_print_relative_time (char const *item,
parser_control const *pc)
 %token tYEAR_UNIT tMONTH_UNIT tHOUR_UNIT tMINUTE_UNIT tSEC_UNIT
 %token <intval> tDAY_UNIT tDAY_SHIFT

-%token <intval> tDAY tDAYZONE tLOCAL_ZONE tMERIDIAN
+%token <intval> tDAY tDAYZONE tLOCAL_ZONE tMERIDIAN tMERIDIAN_WITH_ZONE
 %token <intval> tMONTH tORDINAL tZONE

 %token <textintval> tSNUMBER tUNUMBER
@@ -698,6 +698,27 @@ time:
         set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec);
         pc->meridian = $6;
       }
+  | tUNUMBER tMERIDIAN_WITH_ZONE tSNUMBER o_colon_minutes
+      {
+        set_hhmmss (pc, $1.value, 0, 0, 0);
+        pc->meridian = $2;
+        pc->zones_seen++;
+        if (! time_zone_hhmm (pc, $3, $4)) YYABORT;
+      }
+  | tUNUMBER ':' tUNUMBER tMERIDIAN_WITH_ZONE tSNUMBER o_colon_minutes
+      {
+        set_hhmmss (pc, $1.value, $3.value, 0, 0);
+        pc->meridian = $4;
+        pc->zones_seen++;
+        if (! time_zone_hhmm (pc, $5, $6)) YYABORT;
+      }
+  | tUNUMBER ':' tUNUMBER ':' unsigned_seconds tMERIDIAN_WITH_ZONE
tSNUMBER o_colon_minutes
+      {
+        set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec);
+        pc->meridian = $6;
+        pc->zones_seen++;
+        if (! time_zone_hhmm (pc, $7, $8)) YYABORT;
+      }
   | iso_8601_time
   ;

@@ -1527,14 +1548,19 @@ yylex (union YYSTYPE *lvalp, parser_control *pc)

           *p = '\0';
           tp = lookup_word (pc, buff);
-          if (! tp)
+          if (tp)
             {
-              if (debugging (pc))
-                dbg_printf (_("error: unknown word '%s'\n"), buff);
-              return '?';
+              lvalp->intval = tp->value;
+              if (tp->type == tMERIDIAN)
+                {
+                  char const *p = pc->input;
+                  while (*p && c_isspace (*p))
+                    p++;
+                  if (*p == '-' || *p == '+')
+                    return tMERIDIAN_WITH_ZONE;
+                }
+              return tp->type;
             }
-          lvalp->intval = tp->value;
-          return tp->type;
         }

       if (c != '(')
diff --git a/tests/test-parse-datetime.c b/tests/test-parse-datetime.c
index 546b383c55..9766ed7a13 100644
--- a/tests/test-parse-datetime.c
+++ b/tests/test-parse-datetime.c
@@ -335,6 +335,15 @@ main (_GL_UNUSED int argc, char **argv)
   ASSERT (result.tv_sec == result2.tv_sec
           && result.tv_nsec == result2.tv_nsec);

+  /* Check that timeone works with AM/PM */
+  p = "2024-01-01 8PM -08:00";
+  expected.tv_sec = 1704168000;
+  expected.tv_nsec = 0;
+  ASSERT (parse_datetime (&result, p, NULL));
+  LOG (p, expected, result);
+  ASSERT (expected.tv_sec == result.tv_sec
+          && expected.tv_nsec == result.tv_nsec);
+

   /* TZ out of range should cause parse_datetime failure */
   now.tv_sec = SOME_TIMEPOINT + 4711;
[Message part 2 (text/html, inline)]

This bug report was last modified 44 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.