Adding the new format would be straightforward if not for the existing
decimal/nanoseconds parsing. For now, while parsing through the decimal I check for a later second period. When found, I abort the decimal parsing and return a
normal value. I also set a flag for the next yylex call which will run into
this second period. Probably not the best way to do it, advice on a better
solution welcome.
-- 8< --
* lib/parse-datetime.y: don't parse decimal fractions when detecting second period
---
 lib/parse-datetime.y | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/lib/parse-datetime.y b/lib/parse-datetime.y
index e487ad9552..88c20b0dd0 100644
--- a/lib/parse-datetime.y
+++ b/lib/parse-datetime.y
@@ -224,6 +224,8 @@ typedef struct
   idx_t zones_seen;
   bool year_seen;

+  bool not_decimal;
+
 #ifdef GNULIB_PARSE_DATETIME2
   /* Print debugging output to stderr.  */
   bool parse_datetime_debug;
@@ -1473,8 +1475,15 @@ yylex (union YYSTYPE *lvalp, parser_control *pc)

           if ((c == '.' || c == ',') && c_isdigit (p[1]))
             {
+              /* We are at the second period in a DD.MM.YYYY date */
+              if (pc->not_decimal)
+                {
+                  pc->not_decimal = false;
+                  goto normal_value;
+                }
               time_t s = value;
               int digits;
+              char const *old_p = p;

               /* Accumulate fraction, to ns precision.  */
               p++;
@@ -1482,6 +1491,12 @@ yylex (union YYSTYPE *lvalp, parser_control *pc)
               for (digits = 2; digits <= LOG10_BILLION; digits++)
                 {
                   ns *= 10;
+                  /* Don't parse DD.MM.YYYY dates as a decimal  */
+                  if (*p == '.') {
+                    p = old_p;
+                    pc->not_decimal = true;
+                    goto normal_value;
+                  }
                   if (c_isdigit (*p))
                     ns += *p++ - '0';
                 }
@@ -1514,6 +1529,7 @@ yylex (union YYSTYPE *lvalp, parser_control *pc)
             }
           else
             {
+             normal_value:
               lvalp->textintval.negative = sign < 0;
               lvalp->textintval.value = value;
               lvalp->textintval.digits = p - pc->input;
@@ -1864,6 +1880,7 @@ parse_datetime_body (struct timespec *result, char const *p,
   pc.dsts_seen = 0;
   pc.zones_seen = 0;
   pc.year_seen = false;
+  pc.not_decimal = false;
   pc.debug_dates_seen = false;
   pc.debug_days_seen = false;
   pc.debug_times_seen = false;
--
2.43.0

Reply via email to