bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] getdate add a week when the wday is the same as the current


From: Giuseppe Scrivano
Subject: Re: [PATCH] getdate add a week when the wday is the same as the current one
Date: Fri, 01 May 2009 15:58:35 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.92 (gnu/linux)

Hello,

I fixed the regression you found and added some new tests.

$ ./date -d "fri" +%a.%F
ven.2009-05-01

$ date -d "fri" +%a.%F
ven.2009-05-01

and:

$ ./date -d "next fri" +%a.%F
ven.2009-05-08

$ date -d "next fri" +%a.%F
ven.2009-05-01

Regards,
Giuseppe

>From 0e1af7775a82aed00331a535ddadee2753d12e5e Mon Sep 17 00:00:00 2001
From: Giuseppe Scrivano <address@hidden>
Date: Fri, 1 May 2009 15:44:30 +0200
Subject: [PATCH] 
=?utf-8?q?*=20lib/getdate.y=20(get=5Fdate):=20Correct=20the=20calculation=20of=20tm=5Fmday=20so
=20that=20e.g.,=20"next=20tues"=20(when=20run=20on=20a=20tuesday)=20results=20in=20a=20date
=20that=20is=20one=20week=20in=20the=20future,=20and=20not=20today's=20date.
=20I.e.,=20add=20a=20week=20when=20the=20wday=20is=20the=20same=20as=20the=20current=20one.
=20Reported=20by=20Tom=20Broadhurst=20in=20http://savannah.gnu.org/bugs/=3F25406,
=20and=20earlier=20by=20Martin=20Bernreuther=20and=20Jan=20Min=C3=A1=C5=99.
=20*=20tests/test-getdate.c=20(main):=20Check=20that=20"next=20DAY"=20is=20always=20in
=20the=20future.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

---
 lib/getdate.y        |   10 +++++---
 tests/test-getdate.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/lib/getdate.y b/lib/getdate.y
index 877b264..786e873 100644
--- 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 @@ zone:
 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 @@ get_date (struct timespec *result, char const *p, struct 
timespec const *now)
       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)
diff --git a/tests/test-getdate.c b/tests/test-getdate.c
index 7dfb09e..73c3ad1 100644
--- 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 @@ main (int argc, char **argv)
   struct timespec result2;
   struct timespec now;
   const char *p;
+  int i;
 
   set_program_name (argv[0]);
 
@@ -211,5 +228,42 @@ main (int argc, char **argv)
   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;
 }
-- 
1.6.2.1

Jim Meyering <address@hidden> writes:

> Giuseppe Scrivano wrote:
>> This patch includes all your suggestions and new tests for
>> test-getdate.c.
>
> Thanks for the quick test addition!
> I want the summary line to start with "getdate: "
> and do be "high-level descriptive" so I moved your
> "add a week..." sentence into the body of the log.
> Also, I kept the TAB-oriented indentation and made
> Bruno's simplification (Thanks, Bruno!).
>
> Regarding the test, I added a "const" and tweaked formatting
> so the continued expression starts with "&&" rather than
> leaving the operator at the end of the preceding line.
> That is the prevailing and recommended style.
>
> However, there is a problem.
> With this change, today (a Friday), ./date -d fri
> prints the date for a week from today.
> Without the patch, it prints today's date.
> That is a regression, and shows that we'll need
> several more tests.
>
> If you make further changes, please use the following
> as a basis, so I don't have to change your spaces to TABs
> again or to adjust the content or formatting of the commit log.
>
>
> From 664db25a03246f510793d74fce674b68f32d1dc3 Mon Sep 17 00:00:00 2001
> From: Giuseppe Scrivano <address@hidden>
> Date: Fri, 1 May 2009 09:23:20 +0200
> Subject: [PATCH] getdate: correctly interpret "next monday" when run on a 
> Monday
> MIME-Version: 1.0
> Content-Type: text/plain; charset=utf-8
> Content-Transfer-Encoding: 8bit
>
> * 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.
> ---
>  lib/getdate.y        |    6 ++++--
>  tests/test-getdate.c |   30 ++++++++++++++++++++++++++++++
>  2 files changed, 34 insertions(+), 2 deletions(-)
>
> diff --git a/lib/getdate.y b/lib/getdate.y
> index 877b264..48bf391 100644
> --- 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
> @@ -1435,7 +1435,9 @@ get_date (struct timespec *result, char const *p, 
> struct timespec const *now)
>        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)
> diff --git a/tests/test-getdate.c b/tests/test-getdate.c
> index 7dfb09e..9cee073 100644
> --- 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 @@ main (int argc, char **argv)
>    struct timespec result2;
>    struct timespec now;
>    const char *p;
> +  int i;
>
>    set_program_name (argv[0]);
>
> @@ -211,5 +228,18 @@ main (int argc, char **argv)
>    ASSERT (result.tv_sec == result2.tv_sec
>         && result.tv_nsec == result2.tv_nsec);
>
> +  /* Check that every 'next DAY' is in the 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);
> +    }
> +
>    return 0;
>  }
> --
> 1.6.3.rc3.212.g8c698

reply via email to

[Prev in Thread] Current Thread [Next in Thread]