summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2000-06-15 07:57:58 +0000
committerJim Meyering <jim@meyering.net>2000-06-15 07:57:58 +0000
commitb7aa5f32069533fce1ffeea59d717354af84ee9e (patch)
treef12483467460b796c080bae1bbf60ce8d5a1d08d /lib
parentc787140255237278fd0d1055b5ebf3923805f316 (diff)
downloadcoreutils-b7aa5f32069533fce1ffeea59d717354af84ee9e.tar.xz
(get_date): Apply relative times after time zone indicator, not before.
Diffstat (limited to 'lib')
-rw-r--r--lib/getdate.y30
1 files changed, 25 insertions, 5 deletions
diff --git a/lib/getdate.y b/lib/getdate.y
index 4b7c2e9c8..3210e5367 100644
--- a/lib/getdate.y
+++ b/lib/getdate.y
@@ -85,7 +85,7 @@
#define TM_YEAR_BASE 1900
#define HOUR(x) ((x) * 60)
-
+
/* An integer value, and the number of digits in its textual
representation. */
typedef struct
@@ -168,7 +168,7 @@ static int yylex ();
/* This grammar has 13 shift/reduce conflicts. */
%expect 13
-
+
%union
{
int intval;
@@ -987,9 +987,6 @@ get_date (const char *p, const time_t *now)
{
tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
}
- tm.tm_hour += pc.rel_hour;
- tm.tm_min += pc.rel_minutes;
- tm.tm_sec += pc.rel_seconds;
/* Let mktime deduce tm_isdst if we have an absolute time stamp,
or if the relative time stamp mentions days, months, or years. */
@@ -1061,6 +1058,29 @@ get_date (const char *p, const time_t *now)
Start -= delta;
}
+ /* Add relative hours, minutes, and seconds. Ignore leap seconds;
+ i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
+ leap second. Typically this is not what the user wants, but it's
+ too hard to do it the other way, because the time zone indicator
+ must be applied before relative times, and if mktime is applied
+ again the time zone will be lost. */
+ {
+ time_t t0 = Start;
+ long d1 = 60 * 60 * (long) pc.rel_hour;
+ time_t t1 = t0 + d1;
+ long d2 = 60 * (long) pc.rel_minutes;
+ time_t t2 = t1 + d2;
+ int d3 = pc.rel_seconds;
+ time_t t3 = t2 + d3;
+ if ((d1 / (60 * 60) ^ pc.rel_hour)
+ | (d2 / 60 ^ pc.rel_minutes)
+ | ((t0 + d1 < t0) ^ (d1 < 0))
+ | ((t1 + d2 < t1) ^ (d2 < 0))
+ | ((t2 + d3 < t2) ^ (d3 < 0)))
+ return -1;
+ Start = t3;
+ }
+
return Start;
}