From: Gabriel <[email protected]> * doc/parse-datetime.texi: Document dd.mm.yy support. * lib/parse-datetime.y: Add grammar for dd.mm.yy and dd.mm., and logic to distinguish from tUDECIMAL_NUMBER. --- ChangeLog | 7 +++++++ doc/parse-datetime.texi | 4 ++++ lib/parse-datetime.y | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog index 338d1fb31d..756eaec307 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2026-02-08 Gabriel <[email protected]> + + parse-datetime: support dd.mm.yy format + * doc/parse-datetime.texi: Document dd.mm.yy support. + * lib/parse-datetime.y: Add grammar for dd.mm.yy and dd.mm., + and logic to distinguish from tUDECIMAL_NUMBER. + 2026-02-08 Pádraig Brady <[email protected]> cpu-supports: fix license in source headers diff --git a/doc/parse-datetime.texi b/doc/parse-datetime.texi index b97be4a813..bbf645ae9a 100644 --- a/doc/parse-datetime.texi +++ b/doc/parse-datetime.texi @@ -172,6 +172,7 @@ numerically or literally. All these strings specify the same calendar date: 22-11-14 # Assume 19xx for 69 through 99, # 20xx for 00 through 68 (not recommended). 11/14/2022 # Common U.S. writing. +14.11.2022 # Common European writing. 14 November 2022 14 Nov 2022 # Three-letter abbreviations always allowed. November 14, 2022 @@ -184,6 +185,7 @@ used, or the current year if none. For example: @example 11/14 +14.11. nov 14 @end example @@ -200,6 +202,8 @@ is added to it; otherwise, if @var{year} is less than 100, then 1900 is added to it. The construct @samp{@var{month}/@var{day}/@var{year}}, popular in the United States, is accepted. Also @samp{@var{month}/@var{day}}, omitting the year. +Similarly, the construct @samp{@var{day}.@var{month}.@var{year}}, popular in +Europe, and its short form @samp{@var{day}.@var{month}.} are accepted. @cindex month names in date strings @cindex abbreviations for months diff --git a/lib/parse-datetime.y b/lib/parse-datetime.y index 85a7a92cc0..33e0215541 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; @@ -573,8 +575,8 @@ debug_print_relative_time (char const *item, parser_control const *pc) %parse-param { parser_control *pc } %lex-param { parser_control *pc } -/* This grammar has 31 shift/reduce conflicts. */ -%expect 31 +/* This grammar has 32 shift/reduce conflicts. */ +%expect 32 %union { @@ -847,6 +849,19 @@ date: pc->year = $5; } } + | tUNUMBER '.' tUNUMBER '.' + { + /* E.g., 17.6. */ + pc->day = $1.value; + pc->month = $3.value; + } + | tUNUMBER '.' tUNUMBER '.' tUNUMBER + { + /* E.g., 17.6.1992 */ + pc->day = $1.value; + pc->month = $3.value; + pc->year = $5; + } | tUNUMBER tMONTH tSNUMBER { /* E.g., 17-JUN-1992. */ @@ -1460,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++; @@ -1469,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'; } @@ -1501,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; @@ -1851,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.52.0
