[PROPOSED PATCH 1/4] Have zdump output gmtoff= even on platforms lacking TM_GMTOFF.
* zdump.c (adjusted_yday, gmtoff): New functions. (show): Use new function gmtoff to output gmtoff= even on platforms that do not define TM_GMTOFF. * NEWS: Document this. --- NEWS | 3 +++ zdump.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 21e85a7..618ddb7 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,9 @@ Unreleased, experimental changes Changes affecting code + zdump -V and -v now output gmtoff= values on all platforms, + not merely on platforms defining TM_GMTOFF. + The tz library's localtime and mktime functions now set tzname to a value appropriate for the requested time stamp, and zdump now uses this on platforms not defining TM_ZONE, fixing a 2014g regression. diff --git a/zdump.c b/zdump.c index 0aa94fc..92dd3c1 100644 --- a/zdump.c +++ b/zdump.c @@ -851,19 +851,54 @@ delta(struct tm * newp, struct tm *oldp) return result; } +/* Return A->tm_yday, adjusted to compare it fairly to B->tm_yday. + Assume A and B differ by at most one year. */ +static int +adjusted_yday(struct tm const *a, struct tm const *b) +{ + int yday = a->tm_yday; + if (b->tm_year < a->tm_year) + yday += 365 + isleap_sum(b->tm_year, TM_YEAR_BASE); + return yday; +} + +/* If A is the broken-down local time and B the broken-down UTC for + the same instant, return A's UTC offset in seconds, where positive + offsets are east of Greenwich. On failure, return LONG_MIN. */ +static long +gmtoff(struct tm const *a, struct tm const *b) +{ +#ifdef TM_GMTOFF + return a->TM_GMTOFF; +#else + if (! b) + return LONG_MIN; + else { + int ayday = adjusted_yday(a, b); + int byday = adjusted_yday(b, a); + int days = ayday - byday; + long hours = a->tm_hour - b->tm_hour + 24 * days; + long minutes = a->tm_min - b->tm_min + 60 * hours; + long seconds = a->tm_sec - b->tm_sec + 60 * minutes; + return seconds; + } +#endif +} + static void show(timezone_t tz, char *zone, time_t t, bool v) { register struct tm * tmp; - struct tm tm; + register struct tm * gmtmp; + struct tm tm, gmtm; printf("%-*s ", longest, zone); if (v) { - tmp = my_gmtime_r(&t, &tm); - if (tmp == NULL) { + gmtmp = my_gmtime_r(&t, &gmtm); + if (gmtmp == NULL) { printf(tformat(), t); } else { - dumptime(tmp); + dumptime(gmtmp); printf(" UT"); } printf(" = "); @@ -874,10 +909,10 @@ show(timezone_t tz, char *zone, time_t t, bool v) if (*abbr(tmp) != '\0') printf(" %s", abbr(tmp)); if (v) { + long off = gmtoff(tmp, gmtmp); printf(" isdst=%d", tmp->tm_isdst); -#ifdef TM_GMTOFF - printf(" gmtoff=%ld", tmp->TM_GMTOFF); -#endif /* defined TM_GMTOFF */ + if (off != LONG_MIN) + printf(" gmtoff=%ld", off); } } printf("\n"); -- 1.9.3
--- NEWS | 2 ++ zdump.8 | 17 +++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 618ddb7..7f96547 100644 --- a/NEWS +++ b/NEWS @@ -44,6 +44,8 @@ Unreleased, experimental changes Changes affecting documentation and commentary + zdump's gmtoff=N output is now documented. + zdump -c's treatment of years is now documented to use the Gregorian calendar and Universal Time without leap seconds, and its behavior at cutoff boundaries is now documented better. diff --git a/zdump.8 b/zdump.8 index e793cbf..dd36331 100644 --- a/zdump.8 +++ b/zdump.8 @@ -30,12 +30,17 @@ the time one day after the lowest possible time value, the times both one second before and exactly at each detected time discontinuity, the time at one day less than the highest possible time value, -and the time at the highest possible time value, -Each line ends with -.B isdst=1 -if the given time is Daylight Saving Time or -.B isdst=0 -otherwise. +and the time at the highest possible time value. +Each line is followed by +.BI isdst= D +where +.I D +is 1 if the given time is Daylight Saving Time and is 0 otherwise. +Each line is also followed by +.BI gmtoff= N +if the given local time is known to be +.I N +seconds east of Greenwich. .TP .B \*-V Like -- 1.9.3
* zdump.c (abbr): Don't assume localtime sets tm_isdst to 1 for daylight saving time; any positive value will do. --- zdump.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/zdump.c b/zdump.c index 92dd3c1..37a0926 100644 --- a/zdump.c +++ b/zdump.c @@ -926,9 +926,8 @@ abbr(struct tm const *tmp) #ifdef TM_ZONE return tmp->TM_ZONE; #else - return ((0 <= tmp->tm_isdst && tmp->tm_isdst <= 1 - && tzname[tmp->tm_isdst]) - ? tzname[tmp->tm_isdst] + return (0 <= tmp->tm_isdst && tzname[0 < tmp->tm_isdst] + ? tzname[0 < tmp->tm_isdst] : ""); #endif } -- 1.9.3
--- NEWS | 3 ++- zdump.8 | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 7f96547..06e7094 100644 --- a/NEWS +++ b/NEWS @@ -44,7 +44,8 @@ Unreleased, experimental changes Changes affecting documentation and commentary - zdump's gmtoff=N output is now documented. + zdump's gmtoff=N output is now documented, and its isdst=D output + is now documented to possibly output D values other than 0 or 1. zdump -c's treatment of years is now documented to use the Gregorian calendar and Universal Time without leap seconds, diff --git a/zdump.8 b/zdump.8 index dd36331..be220fa 100644 --- a/zdump.8 +++ b/zdump.8 @@ -35,7 +35,9 @@ Each line is followed by .BI isdst= D where .I D -is 1 if the given time is Daylight Saving Time and is 0 otherwise. +is positive, zero, or negative depending on whether +the given time is daylight saving time, standard time, +or an unknown time type, respectively. Each line is also followed by .BI gmtoff= N if the given local time is known to be -- 1.9.3
participants (1)
-
Paul Eggert