Mercurial > hg > octave-lyh > gnulib-hg
changeset 11535:f16395d91053
getdate: correctly interpret "next monday" when run on a Monday
* lib/getdate.y (get_date): Correct the calculation of tm_mday so
that e.g., "next tues" (when run on a tuesday) results in a date
that is one week in the future, and not today's date.
I.e., add a week when the wday is the same as the current one.
Reported by Tom Broadhurst in http://savannah.gnu.org/bugs/?25406,
and earlier by Martin Bernreuther and Jan Minář.
* tests/test-getdate.c (main): Check that "next DAY" is always in
the future and that "last DAY" is always in the past.
author | Giuseppe Scrivano <gscrivano@gnu.org> |
---|---|
date | Fri, 01 May 2009 09:23:20 +0200 |
parents | 9f608fba8b1c |
children | 30ee15176b4d |
files | ChangeLog lib/getdate.y tests/test-getdate.c |
diffstat | 3 files changed, 72 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2009-05-03 Giuseppe Scrivano <gscrivano@gnu.org> + + getdate: correctly interpret "next monday" when run on a Monday + * lib/getdate.y (get_date): Correct the calculation of tm_mday so + that e.g., "next tues" (when run on a tuesday) results in a date + that is one week in the future, and not today's date. + I.e., add a week when the wday is the same as the current one. + Reported by Tom Broadhurst in http://savannah.gnu.org/bugs/?25406, + and earlier by Martin Bernreuther and Jan Minář. + * tests/test-getdate.c (main): Check that "next DAY" is always in + the future and that "last DAY" is always in the past. + 2009-05-02 Jim Meyering <meyering@redhat.com> build: ensure that a release build fails when a submodule is unclean
--- a/lib/getdate.y +++ b/lib/getdate.y @@ -1,7 +1,7 @@ %{ /* Parse a string into an internal time stamp. - Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -404,12 +404,12 @@ day: tDAY { - pc->day_ordinal = 1; + pc->day_ordinal = 0; pc->day_number = $1; } | tDAY ',' { - pc->day_ordinal = 1; + pc->day_ordinal = 0; pc->day_number = $1; } | tORDINAL tDAY @@ -1435,7 +1435,9 @@ if (pc.days_seen && ! pc.dates_seen) { tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7 - + 7 * (pc.day_ordinal - (0 < pc.day_ordinal))); + + 7 * (pc.day_ordinal + - (0 < pc.day_ordinal + && tm.tm_wday != pc.day_number))); tm.tm_isdst = -1; Start = mktime (&tm); if (Start == (time_t) -1)
--- a/tests/test-getdate.c +++ b/tests/test-getdate.c @@ -48,6 +48,22 @@ #define LOG(str, now, res) (void) 0 #endif +static const char* const day_table[] = +{ + "SUNDAY", + "MONDAY", + "TUESDAY", + "TUES", + "WEDNESDAY", + "WEDNES", + "THURSDAY", + "THUR", + "THURS", + "FRIDAY", + "SATURDAY", + NULL +}; + int main (int argc, char **argv) { @@ -55,6 +71,7 @@ struct timespec result2; struct timespec now; const char *p; + int i; set_program_name (argv[0]); @@ -211,5 +228,42 @@ ASSERT (result.tv_sec == result2.tv_sec && result.tv_nsec == result2.tv_nsec); + /* Check that every 'last/next DAY' is in the past/future. */ + for (i = 0; day_table[i]; i++) + { + char tmp[32]; + sprintf (tmp, "NEXT %s", day_table[i]); + now.tv_sec = 4711; + now.tv_nsec = 1267; + ASSERT (get_date (&result, tmp, &now)); + LOG (tmp, now, result); + ASSERT (result.tv_sec > now.tv_sec + && result.tv_nsec == 0); + + sprintf (tmp, "LAST %s", day_table[i]); + now.tv_sec = 4711; + now.tv_nsec = 1267; + ASSERT (get_date (&result, tmp, &now)); + LOG (tmp, now, result); + ASSERT (result.tv_sec < now.tv_sec + && result.tv_nsec == 0); + } + + p = "THURSDAY UTC+00"; /* The epoch was on Thursday. */ + now.tv_sec = 0; + now.tv_nsec = 0; + ASSERT (get_date (&result, p, &now)); + LOG (p, now, result); + ASSERT (result.tv_sec == now.tv_sec + && result.tv_nsec == now.tv_nsec); + + p = "FRIDAY UTC+00"; + now.tv_sec = 0; + now.tv_nsec = 0; + ASSERT (get_date (&result, p, &now)); + LOG (p, now, result); + ASSERT (result.tv_sec >= now.tv_sec + && result.tv_nsec == now.tv_nsec); + return 0; }