Merge branch '170424' of github.com:jwpi/util-linux
* '170424' of github.com:jwpi/util-linux: parse-date: time_zone_hhmm() bug fixes parse-date: remove unused ordinal_day_seen parse-date: remove unused year_seen parse-date: refactor tm_diff() parse-date: use to_uchar() instead of assignment. parse-date: use uintmax_t where appropriate parse-date: use int where appropriate parse-date: use intmax_t where appropriate parse-date: remove unused EPOCH_YEAR parse-date: replace ISDIGIT with c_isdigit
This commit is contained in:
commit
eba71dd06c
178
lib/parse-date.y
178
lib/parse-date.y
|
@ -92,17 +92,6 @@
|
||||||
# define _STDLIB_H 1
|
# define _STDLIB_H 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* ISDIGIT differs from isdigit, as follows:
|
|
||||||
* - Its arg may be any int or unsigned int; it need not be an unsigned char
|
|
||||||
* or EOF.
|
|
||||||
* - It's typically faster.
|
|
||||||
* POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
|
|
||||||
* isdigit unless it's important to use the locale's definition
|
|
||||||
* of "digit" even when the host does not conform to POSIX.
|
|
||||||
*/
|
|
||||||
#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shift A right by B bits portably, by dividing A by 2**B and
|
* Shift A right by B bits portably, by dividing A by 2**B and
|
||||||
* truncating towards minus infinity. A and B should be free of side
|
* truncating towards minus infinity. A and B should be free of side
|
||||||
|
@ -120,7 +109,6 @@
|
||||||
? (a) >> (b) \
|
? (a) >> (b) \
|
||||||
: (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
|
: (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
|
||||||
|
|
||||||
#define EPOCH_YEAR 1970
|
|
||||||
#define TM_YEAR_BASE 1900
|
#define TM_YEAR_BASE 1900
|
||||||
|
|
||||||
#define HOUR(x) ((x) * 60)
|
#define HOUR(x) ((x) * 60)
|
||||||
|
@ -145,7 +133,7 @@ static unsigned char to_uchar (char ch) { return ch; }
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int negative;
|
int negative;
|
||||||
long int value;
|
intmax_t value;
|
||||||
size_t digits;
|
size_t digits;
|
||||||
} textint;
|
} textint;
|
||||||
|
|
||||||
|
@ -163,13 +151,13 @@ enum { BILLION = 1000000000, LOG10_BILLION = 9 };
|
||||||
|
|
||||||
/* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */
|
/* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
long int year;
|
intmax_t year;
|
||||||
long int month;
|
intmax_t month;
|
||||||
long int day;
|
intmax_t day;
|
||||||
long int hour;
|
intmax_t hour;
|
||||||
long int minutes;
|
intmax_t minutes;
|
||||||
time_t seconds;
|
time_t seconds;
|
||||||
long int ns;
|
int ns;
|
||||||
} relative_time;
|
} relative_time;
|
||||||
|
|
||||||
#if HAVE_COMPOUND_LITERALS
|
#if HAVE_COMPOUND_LITERALS
|
||||||
|
@ -184,7 +172,7 @@ typedef struct {
|
||||||
const char *input;
|
const char *input;
|
||||||
|
|
||||||
/* N, if this is the Nth Tuesday. */
|
/* N, if this is the Nth Tuesday. */
|
||||||
long int day_ordinal;
|
intmax_t day_ordinal;
|
||||||
|
|
||||||
/* Day of week; Sunday is 0. */
|
/* Day of week; Sunday is 0. */
|
||||||
int day_number;
|
int day_number;
|
||||||
|
@ -193,17 +181,17 @@ typedef struct {
|
||||||
int local_isdst;
|
int local_isdst;
|
||||||
|
|
||||||
/* Time zone, in minutes east of UTC. */
|
/* Time zone, in minutes east of UTC. */
|
||||||
long int time_zone;
|
int time_zone;
|
||||||
|
|
||||||
/* Style used for time. */
|
/* Style used for time. */
|
||||||
int meridian;
|
int meridian;
|
||||||
|
|
||||||
/* Gregorian year, month, day, hour, minutes, seconds, and ns. */
|
/* Gregorian year, month, day, hour, minutes, seconds, and ns. */
|
||||||
textint year;
|
textint year;
|
||||||
long int month;
|
intmax_t month;
|
||||||
long int day;
|
intmax_t day;
|
||||||
long int hour;
|
intmax_t hour;
|
||||||
long int minutes;
|
intmax_t minutes;
|
||||||
struct timespec seconds; /* includes nanoseconds */
|
struct timespec seconds; /* includes nanoseconds */
|
||||||
|
|
||||||
/* Relative year, month, day, hour, minutes, seconds, and ns. */
|
/* Relative year, month, day, hour, minutes, seconds, and ns. */
|
||||||
|
@ -218,10 +206,6 @@ typedef struct {
|
||||||
size_t dsts_seen;
|
size_t dsts_seen;
|
||||||
size_t times_seen;
|
size_t times_seen;
|
||||||
size_t zones_seen;
|
size_t zones_seen;
|
||||||
size_t year_seen;
|
|
||||||
|
|
||||||
/* 1 if the user specified explicit ordinal day value, */
|
|
||||||
int ordinal_day_seen;
|
|
||||||
|
|
||||||
/* Table of local time zone abbreviations, null terminated. */
|
/* Table of local time zone abbreviations, null terminated. */
|
||||||
table local_time_zone_table[3];
|
table local_time_zone_table[3];
|
||||||
|
@ -230,7 +214,7 @@ typedef struct {
|
||||||
union YYSTYPE;
|
union YYSTYPE;
|
||||||
static int yylex (union YYSTYPE *, parser_control *);
|
static int yylex (union YYSTYPE *, parser_control *);
|
||||||
static int yyerror (parser_control const *, char const *);
|
static int yyerror (parser_control const *, char const *);
|
||||||
static long int time_zone_hhmm (parser_control *, textint, long int);
|
static int time_zone_hhmm (parser_control *, textint, textint);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract into *PC any date and time info from a string of digits
|
* Extract into *PC any date and time info from a string of digits
|
||||||
|
@ -241,7 +225,6 @@ static void digits_to_date_time(parser_control *pc, textint text_int)
|
||||||
{
|
{
|
||||||
if (pc->dates_seen && ! pc->year.digits
|
if (pc->dates_seen && ! pc->year.digits
|
||||||
&& ! pc->rels_seen && (pc->times_seen || 2 < text_int.digits)) {
|
&& ! pc->rels_seen && (pc->times_seen || 2 < text_int.digits)) {
|
||||||
pc->year_seen++;
|
|
||||||
pc->year = text_int;
|
pc->year = text_int;
|
||||||
} else {
|
} else {
|
||||||
if (4 < text_int.digits) {
|
if (4 < text_int.digits) {
|
||||||
|
@ -283,8 +266,8 @@ static void apply_relative_time(parser_control *pc, relative_time rel,
|
||||||
|
|
||||||
/* Set PC-> hour, minutes, seconds and nanoseconds members from arguments. */
|
/* Set PC-> hour, minutes, seconds and nanoseconds members from arguments. */
|
||||||
static void
|
static void
|
||||||
set_hhmmss(parser_control *pc, long int hour, long int minutes,
|
set_hhmmss(parser_control *pc, intmax_t hour, intmax_t minutes,
|
||||||
time_t sec, long int nsec)
|
time_t sec, int nsec)
|
||||||
{
|
{
|
||||||
pc->hour = hour;
|
pc->hour = hour;
|
||||||
pc->minutes = minutes;
|
pc->minutes = minutes;
|
||||||
|
@ -306,7 +289,7 @@ set_hhmmss(parser_control *pc, long int hour, long int minutes,
|
||||||
%expect 31
|
%expect 31
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
long int intval;
|
intmax_t intval;
|
||||||
textint textintval;
|
textint textintval;
|
||||||
struct timespec timespec;
|
struct timespec timespec;
|
||||||
relative_time rel;
|
relative_time rel;
|
||||||
|
@ -324,7 +307,7 @@ set_hhmmss(parser_control *pc, long int hour, long int minutes,
|
||||||
%token <textintval> tSNUMBER tUNUMBER
|
%token <textintval> tSNUMBER tUNUMBER
|
||||||
%token <timespec> tSDECIMAL_NUMBER tUDECIMAL_NUMBER
|
%token <timespec> tSDECIMAL_NUMBER tUDECIMAL_NUMBER
|
||||||
|
|
||||||
%type <intval> o_colon_minutes
|
%type <textintval> o_colon_minutes
|
||||||
%type <timespec> seconds signed_seconds unsigned_seconds
|
%type <timespec> seconds signed_seconds unsigned_seconds
|
||||||
|
|
||||||
%type <rel> relunit relunit_snumber dayshift
|
%type <rel> relunit relunit_snumber dayshift
|
||||||
|
@ -419,7 +402,7 @@ o_zone_offset:
|
||||||
zone_offset:
|
zone_offset:
|
||||||
tSNUMBER o_colon_minutes {
|
tSNUMBER o_colon_minutes {
|
||||||
pc->zones_seen++;
|
pc->zones_seen++;
|
||||||
pc->time_zone = time_zone_hhmm (pc, $1, $2);
|
if (! time_zone_hhmm (pc, $1, $2)) YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -472,7 +455,8 @@ zone:
|
||||||
apply_relative_time (pc, $2, 1);
|
apply_relative_time (pc, $2, 1);
|
||||||
}
|
}
|
||||||
| tZONE tSNUMBER o_colon_minutes {
|
| tZONE tSNUMBER o_colon_minutes {
|
||||||
pc->time_zone = $1 + time_zone_hhmm (pc, $2, $3);
|
if (! time_zone_hhmm (pc, $2, $3)) YYABORT;
|
||||||
|
pc->time_zone += $1;
|
||||||
}
|
}
|
||||||
| tDAYZONE {
|
| tDAYZONE {
|
||||||
pc->time_zone = $1 + 60;
|
pc->time_zone = $1 + 60;
|
||||||
|
@ -494,12 +478,10 @@ day:
|
||||||
| tORDINAL tDAY {
|
| tORDINAL tDAY {
|
||||||
pc->day_ordinal = $1;
|
pc->day_ordinal = $1;
|
||||||
pc->day_number = $2;
|
pc->day_number = $2;
|
||||||
pc->ordinal_day_seen = 1;
|
|
||||||
}
|
}
|
||||||
| tUNUMBER tDAY {
|
| tUNUMBER tDAY {
|
||||||
pc->day_ordinal = $1.value;
|
pc->day_ordinal = $1.value;
|
||||||
pc->day_number = $2;
|
pc->day_number = $2;
|
||||||
pc->ordinal_day_seen = 1;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -681,9 +663,10 @@ hybrid:
|
||||||
|
|
||||||
o_colon_minutes:
|
o_colon_minutes:
|
||||||
/* empty */
|
/* empty */
|
||||||
{ $$ = -1; }
|
{ $$.value = $$.digits = 0; }
|
||||||
| ':' tUNUMBER
|
| ':' tUNUMBER {
|
||||||
{ $$ = $2.value; }
|
$$ = $2;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
@ -874,42 +857,38 @@ static table const military_table[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a time zone expressed as HH:MM into an integer count of
|
* Convert a time offset expressed as HH:MM or HHMM into an integer count of
|
||||||
* minutes. If MM is negative, then S is of the form HHMM and needs
|
* minutes. If hh is more than 2 digits then it is of the form HHMM and must be
|
||||||
* to be picked apart; otherwise, S is of the form HH. As specified in
|
* delimited; in that case 'mm' is required to be absent. Otherwise, hh and mm
|
||||||
* http://www.opengroup.org/susv3xbd/xbd_chap08.html#tag_08_03, allow
|
* are used ('mm' contains digits that were prefixed with a colon).
|
||||||
* only valid TZ range, and consider first two digits as hours, if no
|
*
|
||||||
* minutes specified.
|
* POSIX TZ and ISO 8601 both define the maximum offset as 24:59. POSIX also
|
||||||
|
* allows seconds, but currently the parser rejects them. Both require minutes
|
||||||
|
* to be zero padded (2 digits). ISO requires hours to be zero padded, POSIX
|
||||||
|
* does not, either is accepted; which means an invalid ISO offset could pass.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static long int time_zone_hhmm(parser_control *pc, textint s, long int mm)
|
static int time_zone_hhmm(parser_control *pc, textint hh, textint mm)
|
||||||
{
|
{
|
||||||
long int n_minutes;
|
int h, m;
|
||||||
|
|
||||||
/**
|
if (hh.digits > 2 && hh.digits < 5 && mm.digits == 0) {
|
||||||
* If the length of S is 1 or 2 and no minutes are specified,
|
h = hh.value / 100;
|
||||||
* interpret it as a number of hours.
|
m = hh.value % 100;
|
||||||
*/
|
} else if (hh.digits < 3 && (mm.digits == 0 || mm.digits == 2)) {
|
||||||
if (s.digits <= 2 && mm < 0)
|
h = hh.value;
|
||||||
s.value *= 100;
|
m = hh.negative ? -mm.value : mm.value;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (mm < 0)
|
if (abs(h) > 24 || abs(m) > 59)
|
||||||
n_minutes = (s.value / 100) * 60 + s.value % 100;
|
return 0;
|
||||||
else
|
|
||||||
n_minutes = s.value * 60 + (s.negative ? -mm : mm);
|
|
||||||
|
|
||||||
/**
|
pc->time_zone = h * 60 + m;
|
||||||
* If the absolute number of minutes is larger than 24 hours,
|
return 1;
|
||||||
* arrange to reject it by incrementing pc->zones_seen. Thus,
|
|
||||||
* we allow only values in the range UTC-24:00 to UTC+24:00.
|
|
||||||
*/
|
|
||||||
if (24 * 60 < abs (n_minutes))
|
|
||||||
pc->zones_seen++;
|
|
||||||
|
|
||||||
return n_minutes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int to_hour(long int hours, int meridian)
|
static int to_hour(intmax_t hours, int meridian)
|
||||||
{
|
{
|
||||||
switch (meridian) {
|
switch (meridian) {
|
||||||
default: /* Pacify GCC. */
|
default: /* Pacify GCC. */
|
||||||
|
@ -924,7 +903,7 @@ static int to_hour(long int hours, int meridian)
|
||||||
|
|
||||||
static long int to_year(textint textyear)
|
static long int to_year(textint textyear)
|
||||||
{
|
{
|
||||||
long int year = textyear.value;
|
intmax_t year = textyear.value;
|
||||||
|
|
||||||
if (year < 0)
|
if (year < 0)
|
||||||
year = -year;
|
year = -year;
|
||||||
|
@ -969,7 +948,7 @@ static table const * lookup_zone(parser_control const *pc, char const *name)
|
||||||
* The body of this function is taken directly from the GNU C Library;
|
* The body of this function is taken directly from the GNU C Library;
|
||||||
* see src/strftime.c.
|
* see src/strftime.c.
|
||||||
*/
|
*/
|
||||||
static long int tm_diff(struct tm const *a, struct tm const *b)
|
static int tm_diff(struct tm const *a, struct tm const *b)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Compute intervening leap days correctly even if year is negative.
|
* Compute intervening leap days correctly even if year is negative.
|
||||||
|
@ -982,9 +961,8 @@ static long int tm_diff(struct tm const *a, struct tm const *b)
|
||||||
int a400 = SHR (a100, 2);
|
int a400 = SHR (a100, 2);
|
||||||
int b400 = SHR (b100, 2);
|
int b400 = SHR (b100, 2);
|
||||||
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
|
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
|
||||||
long int ayear = a->tm_year;
|
int years = a->tm_year - b->tm_year;
|
||||||
long int years = ayear - b->tm_year;
|
int days = (365 * years + intervening_leap_days
|
||||||
long int days = (365 * years + intervening_leap_days
|
|
||||||
+ (a->tm_yday - b->tm_yday));
|
+ (a->tm_yday - b->tm_yday));
|
||||||
return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
|
return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
|
||||||
+ (a->tm_min - b->tm_min))
|
+ (a->tm_min - b->tm_min))
|
||||||
|
@ -1002,10 +980,8 @@ static table const * lookup_word(parser_control const *pc, char *word)
|
||||||
int abbrev;
|
int abbrev;
|
||||||
|
|
||||||
/* Make it uppercase. */
|
/* Make it uppercase. */
|
||||||
for (p = word; *p; p++) {
|
for (p = word; *p; p++)
|
||||||
unsigned char ch = *p;
|
*p = c_toupper (to_uchar (*p));
|
||||||
*p = c_toupper (ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (tp = meridian_table; tp->name; tp++)
|
for (tp = meridian_table; tp->name; tp++)
|
||||||
if (strcmp (word, tp->name) == 0)
|
if (strcmp (word, tp->name) == 0)
|
||||||
|
@ -1070,36 +1046,36 @@ static int yylex (union YYSTYPE *lvalp, parser_control *pc)
|
||||||
while (c = *pc->input, c_isspace (c))
|
while (c = *pc->input, c_isspace (c))
|
||||||
pc->input++;
|
pc->input++;
|
||||||
|
|
||||||
if (ISDIGIT (c) || c == '-' || c == '+') {
|
if (c_isdigit (c) || c == '-' || c == '+') {
|
||||||
char const *p;
|
char const *p;
|
||||||
int sign;
|
int sign;
|
||||||
unsigned long int value;
|
uintmax_t value;
|
||||||
if (c == '-' || c == '+') {
|
if (c == '-' || c == '+') {
|
||||||
sign = c == '-' ? -1 : 1;
|
sign = c == '-' ? -1 : 1;
|
||||||
while (c = *++pc->input, c_isspace (c))
|
while (c = *++pc->input, c_isspace (c))
|
||||||
continue;
|
continue;
|
||||||
if (! ISDIGIT (c))
|
if (! c_isdigit (c))
|
||||||
/* skip the '-' sign */
|
/* skip the '-' sign */
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else
|
||||||
sign = 0;
|
sign = 0;
|
||||||
p = pc->input;
|
p = pc->input;
|
||||||
for (value = 0; ; value *= 10) {
|
for (value = 0; ; value *= 10) {
|
||||||
unsigned long int value1 = value + (c - '0');
|
uintmax_t value1 = value + (c - '0');
|
||||||
if (value1 < value)
|
if (value1 < value)
|
||||||
return '?';
|
return '?';
|
||||||
value = value1;
|
value = value1;
|
||||||
c = *++p;
|
c = *++p;
|
||||||
if (! ISDIGIT (c))
|
if (! c_isdigit (c))
|
||||||
break;
|
break;
|
||||||
if (ULONG_MAX / 10 < value)
|
if (UINTMAX_MAX / 10 < value)
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
if ((c == '.' || c == ',') && ISDIGIT (p[1])) {
|
if ((c == '.' || c == ',') && c_isdigit (p[1])) {
|
||||||
time_t s;
|
time_t s;
|
||||||
int ns;
|
int ns;
|
||||||
int digits;
|
int digits;
|
||||||
unsigned long int value1;
|
uintmax_t value1;
|
||||||
|
|
||||||
/* Check for overflow when converting value to
|
/* Check for overflow when converting value to
|
||||||
* time_t.
|
* time_t.
|
||||||
|
@ -1124,7 +1100,7 @@ static int yylex (union YYSTYPE *lvalp, parser_control *pc)
|
||||||
for (digits = 2;
|
for (digits = 2;
|
||||||
digits <= LOG10_BILLION; digits++) {
|
digits <= LOG10_BILLION; digits++) {
|
||||||
ns *= 10;
|
ns *= 10;
|
||||||
if (ISDIGIT (*p))
|
if (c_isdigit (*p))
|
||||||
ns += *p++ - '0';
|
ns += *p++ - '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,12 +1108,12 @@ static int yylex (union YYSTYPE *lvalp, parser_control *pc)
|
||||||
* -Infinity.
|
* -Infinity.
|
||||||
*/
|
*/
|
||||||
if (sign < 0)
|
if (sign < 0)
|
||||||
for (; ISDIGIT (*p); p++)
|
for (; c_isdigit (*p); p++)
|
||||||
if (*p != '0') {
|
if (*p != '0') {
|
||||||
ns++;
|
ns++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (ISDIGIT (*p))
|
while (c_isdigit (*p))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
/* Adjust to the timespec convention, which is
|
/* Adjust to the timespec convention, which is
|
||||||
|
@ -1277,7 +1253,7 @@ int parse_date(struct timespec *result, char const *p,
|
||||||
struct timespec const *now)
|
struct timespec const *now)
|
||||||
{
|
{
|
||||||
time_t Start;
|
time_t Start;
|
||||||
long int Start_ns;
|
intmax_t Start_ns;
|
||||||
struct tm const *tmp;
|
struct tm const *tmp;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
struct tm tm0;
|
struct tm tm0;
|
||||||
|
@ -1383,8 +1359,6 @@ int parse_date(struct timespec *result, char const *p,
|
||||||
pc.local_zones_seen = 0;
|
pc.local_zones_seen = 0;
|
||||||
pc.dsts_seen = 0;
|
pc.dsts_seen = 0;
|
||||||
pc.zones_seen = 0;
|
pc.zones_seen = 0;
|
||||||
pc.year_seen = 0;
|
|
||||||
pc.ordinal_day_seen = 0;
|
|
||||||
|
|
||||||
#if HAVE_STRUCT_TM_TM_ZONE
|
#if HAVE_STRUCT_TM_TM_ZONE
|
||||||
pc.local_time_zone_table[0].name = tmp->tm_zone;
|
pc.local_time_zone_table[0].name = tmp->tm_zone;
|
||||||
|
@ -1513,12 +1487,12 @@ int parse_date(struct timespec *result, char const *p,
|
||||||
* TZ="XXX1:00" and try mktime again.
|
* TZ="XXX1:00" and try mktime again.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
long int time_zone = pc.time_zone;
|
intmax_t time_zone = pc.time_zone;
|
||||||
|
|
||||||
long int abs_time_zone = time_zone < 0
|
intmax_t abs_time_zone = time_zone < 0
|
||||||
? - time_zone : time_zone;
|
? - time_zone : time_zone;
|
||||||
|
|
||||||
long int abs_time_zone_hour
|
intmax_t abs_time_zone_hour
|
||||||
= abs_time_zone / 60;
|
= abs_time_zone / 60;
|
||||||
|
|
||||||
int abs_time_zone_min = abs_time_zone % 60;
|
int abs_time_zone_min = abs_time_zone % 60;
|
||||||
|
@ -1584,7 +1558,7 @@ int parse_date(struct timespec *result, char const *p,
|
||||||
* so this block must follow others that clobber Start.
|
* so this block must follow others that clobber Start.
|
||||||
*/
|
*/
|
||||||
if (pc.zones_seen) {
|
if (pc.zones_seen) {
|
||||||
long int delta = pc.time_zone * 60;
|
intmax_t delta = pc.time_zone * 60;
|
||||||
time_t t1;
|
time_t t1;
|
||||||
#ifdef HAVE_TM_GMTOFF
|
#ifdef HAVE_TM_GMTOFF
|
||||||
delta -= tm.tm_gmtoff;
|
delta -= tm.tm_gmtoff;
|
||||||
|
@ -1612,16 +1586,16 @@ int parse_date(struct timespec *result, char const *p,
|
||||||
* zone indicator must be applied before relative times, and if
|
* zone indicator must be applied before relative times, and if
|
||||||
* mktime is applied again the time zone will be lost.
|
* mktime is applied again the time zone will be lost.
|
||||||
*/
|
*/
|
||||||
long int sum_ns = pc.seconds.tv_nsec + pc.rel.ns;
|
intmax_t sum_ns = pc.seconds.tv_nsec + pc.rel.ns;
|
||||||
long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;
|
intmax_t normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;
|
||||||
time_t t0 = Start;
|
time_t t0 = Start;
|
||||||
long int d1 = 60 * 60 * pc.rel.hour;
|
intmax_t d1 = 60 * 60 * pc.rel.hour;
|
||||||
time_t t1 = t0 + d1;
|
time_t t1 = t0 + d1;
|
||||||
long int d2 = 60 * pc.rel.minutes;
|
intmax_t d2 = 60 * pc.rel.minutes;
|
||||||
time_t t2 = t1 + d2;
|
time_t t2 = t1 + d2;
|
||||||
time_t d3 = pc.rel.seconds;
|
time_t d3 = pc.rel.seconds;
|
||||||
time_t t3 = t2 + d3;
|
time_t t3 = t2 + d3;
|
||||||
long int d4 = (sum_ns - normalized_ns) / BILLION;
|
intmax_t d4 = (sum_ns - normalized_ns) / BILLION;
|
||||||
time_t t4 = t3 + d4;
|
time_t t4 = t3 + d4;
|
||||||
time_t t5 = t4;
|
time_t t5 = t4;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue