diff --git a/libc/stdtime/asctime.c b/libc/stdtime/asctime.c index 6578663c0d35..e0804f16f4dd 100644 --- a/libc/stdtime/asctime.c +++ b/libc/stdtime/asctime.c @@ -1,11 +1,17 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. +*/ + +/* +** Avoid the temptation to punt entirely to strftime; +** the output of strftime is supposed to be locale specific +** whereas the output of asctime is supposed to be constant. */ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)asctime.c 7.9"; +static char elsieid[] = "@(#)asctime.c 8.2"; #endif /* !defined NOID */ #endif /* !defined lint */ @@ -15,7 +21,57 @@ static char elsieid[] = "@(#)asctime.c 7.9"; #include "tzfile.h" /* -** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, Second Edition, 1996-07-12. +** Some systems only handle "%.2d"; others only handle "%02d"; +** "%02.2d" makes (most) everybody happy. +** At least some versions of gcc warn about the %02.2d; +** we conditionalize below to avoid the warning. +*/ +/* +** All years associated with 32-bit time_t values are exactly four digits long; +** some years associated with 64-bit time_t values are not. +** Vintage programs are coded for years that are always four digits long +** and may assume that the newline always lands in the same place. +** For years that are less than four digits, we pad the output with +** leading zeroes to get the newline in the traditional place. +** The -4 ensures that we get four characters of output even if +** we call a strftime variant that produces fewer characters for some years. +** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year, +** but many implementations pad anyway; most likely the standards are buggy. +*/ +#ifdef __GNUC__ +#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n" +#endif /* !defined __GNUC__ */ +/* +** For years that are more than four digits we put extra spaces before the year +** so that code trying to overwrite the newline won't end up overwriting +** a digit within a year and truncating the year (operating on the assumption +** that no output is better than wrong output). +*/ +#ifdef __GNUC__ +#define ASCTIME_FMT_B "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT_B "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %s\n" +#endif /* !defined __GNUC__ */ + +#define STD_ASCTIME_BUF_SIZE 26 +/* +** Big enough for something such as +** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n +** (two three-character abbreviations, five strings denoting integers, +** seven explicit spaces, two explicit colons, a newline, +** and a trailing ASCII nul). +** The values above are for systems where an int is 32 bits and are provided +** as an example; the define below calculates the maximum for the system at +** hand. +*/ +#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1) + +static char buf_asctime[MAX_ASCTIME_BUF_SIZE]; + +/* +** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. */ char * @@ -32,6 +88,8 @@ char * buf; }; register const char * wn; register const char * mn; + char year[INT_STRLEN_MAXIMUM(int) + 2]; + char result[MAX_ASCTIME_BUF_SIZE]; if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) wn = "???"; @@ -40,35 +98,41 @@ char * buf; mn = "???"; else mn = mon_name[timeptr->tm_mon]; /* - ** The X3J11-suggested format is - ** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n" - ** Since the .2 in 02.2d is ignored, we drop it. + ** Use strftime's %Y to generate the year, to avoid overflow problems + ** when computing timeptr->tm_year + TM_YEAR_BASE. + ** Assume that strftime is unaffected by other out-of-range members + ** (e.g., timeptr->tm_mday) when processing "%Y". */ - (void) sprintf(buf, "%.3s %.3s%3d %02d:%02d:%02d %d\n", + (void) strftime(year, sizeof year, "%Y", timeptr); + /* + ** We avoid using snprintf since it's not available on all systems. + */ + (void) sprintf(result, + ((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B), wn, mn, timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec, - TM_YEAR_BASE + timeptr->tm_year); - return buf; + year); + if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) { + (void) strcpy(buf, result); + return buf; + } else { +#ifdef EOVERFLOW + errno = EOVERFLOW; +#else /* !defined EOVERFLOW */ + errno = EINVAL; +#endif /* !defined EOVERFLOW */ + return NULL; + } } /* -** A la X3J11, with core dump avoidance. +** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. */ char * asctime(timeptr) register const struct tm * timeptr; { - /* - ** Big enough for something such as - ** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n - ** (two three-character abbreviations, five strings denoting integers, - ** three explicit spaces, two explicit colons, a newline, - ** and a trailing ASCII nul). - */ - static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) + - 3 + 2 + 1 + 1]; - - return asctime_r(timeptr, result); + return asctime_r(timeptr, buf_asctime); } diff --git a/libc/stdtime/difftime.c b/libc/stdtime/difftime.c index 1d1519e15939..da779773bfdd 100644 --- a/libc/stdtime/difftime.c +++ b/libc/stdtime/difftime.c @@ -1,83 +1,65 @@ /* ** This file is in the public domain, so clarified as of -** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. */ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)difftime.c 7.9"; +static char elsieid[] = "@(#)difftime.c 8.1"; #endif /* !defined NOID */ #endif /* !defined lint */ /*LINTLIBRARY*/ -#include "private.h" - -/* -** Algorithm courtesy Paul Eggert (eggert@twinsun.com). -*/ - -#ifdef HAVE_LONG_DOUBLE -#define long_double long double -#endif /* defined HAVE_LONG_DOUBLE */ -#ifndef HAVE_LONG_DOUBLE -#define long_double double -#endif /* !defined HAVE_LONG_DOUBLE */ +#include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */ double difftime(time1, time0) const time_t time1; const time_t time0; { - time_t delta; - time_t hibit; - - { - time_t tt; - double d; - long_double ld; - - if (sizeof tt < sizeof d) - return (double) time1 - (double) time0; - if (sizeof tt < sizeof ld) - return (long_double) time1 - (long_double) time0; + /* + ** If (sizeof (double) > sizeof (time_t)) simply convert and subtract + ** (assuming that the larger type has more precision). + ** This is the common real-world case circa 2004. + */ + if (sizeof (double) > sizeof (time_t)) + return (double) time1 - (double) time0; + if (!TYPE_INTEGRAL(time_t)) { + /* + ** time_t is floating. + */ + return time1 - time0; + } + if (!TYPE_SIGNED(time_t)) { + /* + ** time_t is integral and unsigned. + ** The difference of two unsigned values can't overflow + ** if the minuend is greater than or equal to the subtrahend. + */ + if (time1 >= time0) + return time1 - time0; + else return -((double) (time0 - time1)); } - if (time1 < time0) - return -difftime(time0, time1); /* - ** As much as possible, avoid loss of precision - ** by computing the difference before converting to double. + ** time_t is integral and signed. + ** Handle cases where both time1 and time0 have the same sign + ** (meaning that their difference cannot overflow). */ - delta = time1 - time0; - if (delta >= 0) - return delta; + if ((time1 < 0) == (time0 < 0)) + return time1 - time0; /* - ** Repair delta overflow. + ** time1 and time0 have opposite signs. + ** Punt if unsigned long is too narrow. */ - hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1); + if (sizeof (unsigned long) < sizeof (time_t)) + return (double) time1 - (double) time0; /* - ** The following expression rounds twice, which means - ** the result may not be the closest to the true answer. - ** For example, suppose time_t is 64-bit signed int, - ** long_double is IEEE 754 double with default rounding, - ** time1 = 9223372036854775807 and time0 = -1536. - ** Then the true difference is 9223372036854777343, - ** which rounds to 9223372036854777856 - ** with a total error of 513. - ** But delta overflows to -9223372036854774273, - ** which rounds to -9223372036854774784, and correcting - ** this by subtracting 2 * (long_double) hibit - ** (i.e. by adding 2**64 = 18446744073709551616) - ** yields 9223372036854776832, which - ** rounds to 9223372036854775808 - ** with a total error of 1535 instead. - ** This problem occurs only with very large differences. - ** It's too painful to fix this portably. - ** We are not alone in this problem; - ** some C compilers round twice when converting - ** large unsigned types to small floating types, - ** so if time_t is unsigned the "return delta" above - ** has the same double-rounding problem with those compilers. + ** Stay calm...decent optimizers will eliminate the complexity below. */ - return delta - 2 * (long_double) hibit; + if (time1 >= 0 /* && time0 < 0 */) + return (unsigned long) time1 + + (unsigned long) (-(time0 + 1)) + 1; + return -(double) ((unsigned long) time0 + + (unsigned long) (-(time1 + 1)) + 1); } diff --git a/libc/stdtime/localtime.c b/libc/stdtime/localtime.c index 33dcd5d052c3..d186080bf351 100644 --- a/libc/stdtime/localtime.c +++ b/libc/stdtime/localtime.c @@ -1,18 +1,17 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. */ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)localtime.c 7.78"; +static char elsieid[] = "@(#)localtime.c 8.9"; #endif /* !defined NOID */ #endif /* !defined lint */ /* -** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu). -** POSIX-style TZ environment variable handling from Guy Harris -** (guy@auspex.com). +** Leap second handling from Bradley White. +** POSIX-style TZ environment variable handling from Guy Harris. */ /*LINTLIBRARY*/ @@ -20,6 +19,20 @@ static char elsieid[] = "@(#)localtime.c 7.78"; #include "private.h" #include "tzfile.h" #include "fcntl.h" +#include "float.h" /* for FLT_MAX and DBL_MAX */ + +#ifndef TZ_ABBR_MAX_LEN +#define TZ_ABBR_MAX_LEN 16 +#endif /* !defined TZ_ABBR_MAX_LEN */ + +#ifndef TZ_ABBR_CHAR_SET +#define TZ_ABBR_CHAR_SET \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" +#endif /* !defined TZ_ABBR_CHAR_SET */ + +#ifndef TZ_ABBR_ERR_CHAR +#define TZ_ABBR_ERR_CHAR '_' +#endif /* !defined TZ_ABBR_ERR_CHAR */ /* ** SunOS 4.1.1 headers lack O_BINARY. @@ -46,16 +59,16 @@ static char elsieid[] = "@(#)localtime.c 7.78"; ** 5. They might reference tm.TM_ZONE after calling offtime. ** What's best to do in the above cases is open to debate; ** for now, we just set things up so that in any of the five cases -** WILDABBR is used. Another possibility: initialize tzname[0] to the +** WILDABBR is used. Another possibility: initialize tzname[0] to the ** string "tzname[0] used before set", and similarly for the other cases. -** And another: initialize tzname[0] to "ERA", with an explanation in the +** And another: initialize tzname[0] to "ERA", with an explanation in the ** manual page of what this "time zone abbreviation" means (doing this so ** that tzname[0] has the "normal" length of three characters). */ #define WILDABBR " " #endif /* !defined WILDABBR */ -static char wildabbr[] = "WILDABBR"; +static char wildabbr[] = WILDABBR; static const char gmt[] = "GMT"; @@ -97,6 +110,8 @@ struct state { int timecnt; int typecnt; int charcnt; + int goback; + int goahead; time_t ats[TZ_MAX_TIMES]; unsigned char types[TZ_MAX_TIMES]; struct ttinfo ttis[TZ_MAX_TYPES]; @@ -121,43 +136,52 @@ struct rule { ** Prototypes for static functions. */ -static long detzcode P((const char * codep)); -static const char * getzname P((const char * strp)); -static const char * getnum P((const char * strp, int * nump, int min, - int max)); -static const char * getsecs P((const char * strp, long * secsp)); -static const char * getoffset P((const char * strp, long * offsetp)); -static const char * getrule P((const char * strp, struct rule * rulep)); -static void gmtload P((struct state * sp)); -static void gmtsub P((const time_t * timep, long offset, - struct tm * tmp)); -static void localsub P((const time_t * timep, long offset, - struct tm * tmp)); -static int increment_overflow P((int * number, int delta)); -static int normalize_overflow P((int * tensptr, int * unitsptr, - int base)); -static void settzname P((void)); -static time_t time1 P((struct tm * tmp, - void(*funcp) P((const time_t *, - long, struct tm *)), - long offset)); -static time_t time2 P((struct tm *tmp, - void(*funcp) P((const time_t *, - long, struct tm*)), - long offset, int * okayp)); -static time_t time2sub P((struct tm *tmp, - void(*funcp) P((const time_t *, - long, struct tm*)), - long offset, int * okayp, int do_norm_secs)); -static void timesub P((const time_t * timep, long offset, - const struct state * sp, struct tm * tmp)); -static int tmcomp P((const struct tm * atmp, - const struct tm * btmp)); -static time_t transtime P((time_t janfirst, int year, - const struct rule * rulep, long offset)); -static int tzload P((const char * name, struct state * sp)); -static int tzparse P((const char * name, struct state * sp, - int lastditch)); +static long detzcode(const char * codep); +static time_t detzcode64(const char * codep); +static int differ_by_repeat(time_t t1, time_t t0); +static const char * getzname(const char * strp); +static const char * getqzname(const char * strp, const int delim); +static const char * getnum(const char * strp, int * nump, int min, + int max); +static const char * getsecs(const char * strp, long * secsp); +static const char * getoffset(const char * strp, long * offsetp); +static const char * getrule(const char * strp, struct rule * rulep); +static void gmtload(struct state * sp); +static struct tm * gmtsub(const time_t * timep, long offset, + struct tm * tmp); +static struct tm * localsub(const time_t * timep, long offset, + struct tm * tmp); +static int increment_overflow(int * number, int delta); +static int leaps_thru_end_of(int y); +static int long_increment_overflow(long * number, int delta); +static int long_normalize_overflow(long * tensptr, + int * unitsptr, int base); +static int normalize_overflow(int * tensptr, int * unitsptr, + int base); +static void settzname(void); +static time_t time1(struct tm * tmp, + struct tm * (*funcp)(const time_t *, + long, struct tm *), + long offset); +static time_t time2(struct tm *tmp, + struct tm * (*funcp)(const time_t *, + long, struct tm*), + long offset, int * okayp); +static time_t time2sub(struct tm *tmp, + struct tm * (*funcp)(const time_t *, + long, struct tm*), + long offset, int * okayp, int do_norm_secs); +static struct tm * timesub(const time_t * timep, long offset, + const struct state * sp, struct tm * tmp); +static int tmcomp(const struct tm * atmp, + const struct tm * btmp); +static time_t transtime(time_t janfirst, int year, + const struct rule * rulep, long offset); +static int typesequiv(const struct state * sp, int a, int b); +static int tzload(const char * name, struct state * sp, + int doextend); +static int tzparse(const char * name, struct state * sp, + int lastditch); #ifdef ALL_STATE static struct state * lclptr; @@ -189,7 +213,7 @@ char * tzname[2] = { ** Except for the strftime function, these functions [asctime, ** ctime, gmtime, localtime] return values in one of two static ** objects: a broken-down time structure and an array of char. -** Thanks to Paul Eggert (eggert@twinsun.com) for noting this. +** Thanks to Paul Eggert for noting this. */ static struct tm tm; @@ -210,14 +234,27 @@ const char * const codep; register long result; register int i; - result = (codep[0] & 0x80) ? ~0L : 0L; + result = (codep[0] & 0x80) ? ~0L : 0; for (i = 0; i < 4; ++i) result = (result << 8) | (codep[i] & 0xff); return result; } +static time_t +detzcode64(codep) +const char * const codep; +{ + register time_t result; + register int i; + + result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0; + for (i = 0; i < 8; ++i) + result = result * 256 + (codep[i] & 0xff); + return result; +} + static void -settzname P((void)) +settzname(void) { register struct state * const sp = lclptr; register int i; @@ -264,16 +301,54 @@ settzname P((void)) tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind]; } + /* + ** Finally, scrub the abbreviations. + ** First, replace bogus characters. + */ + for (i = 0; i < sp->charcnt; ++i) + if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL) + sp->chars[i] = TZ_ABBR_ERR_CHAR; + /* + ** Second, truncate long abbreviations. + */ + for (i = 0; i < sp->typecnt; ++i) { + register const struct ttinfo * const ttisp = &sp->ttis[i]; + register char * cp = &sp->chars[ttisp->tt_abbrind]; + + if (strlen(cp) > TZ_ABBR_MAX_LEN && + strcmp(cp, GRANDPARENTED) != 0) + *(cp + TZ_ABBR_MAX_LEN) = '\0'; + } } static int -tzload(name, sp) +differ_by_repeat(t1, t0) +const time_t t1; +const time_t t0; +{ + if (TYPE_INTEGRAL(time_t) && + TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS) + return 0; + return t1 - t0 == SECSPERREPEAT; +} + +static int +tzload(name, sp, doextend) register const char * name; register struct state * const sp; +register const int doextend; { - register const char * p; - register int i; - register int fid; + register const char * p; + register int i; + register int fid; + register int stored; + register int nread; + union { + struct tzhead tzhead; + char buf[2 * sizeof(struct tzhead) + + 2 * sizeof *sp + + 4 * TZ_MAX_TIMES]; + } u; if (name == NULL && (name = TZDEFAULT) == NULL) return -1; @@ -311,18 +386,13 @@ register struct state * const sp; if ((fid = open(name, OPEN_MODE)) == -1) return -1; } - { - struct tzhead * tzhp; - union { - struct tzhead tzhead; - char buf[sizeof *sp + sizeof *tzhp]; - } u; + nread = read(fid, u.buf, sizeof u.buf); + if (close(fid) < 0 || nread <= 0) + return -1; + for (stored = 4; stored <= 8; stored *= 2) { int ttisstdcnt; int ttisgmtcnt; - i = read(fid, u.buf, sizeof u.buf); - if (close(fid) != 0) - return -1; ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt); ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt); sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt); @@ -337,17 +407,19 @@ register struct state * const sp; (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) || (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) return -1; - if (i - (p - u.buf) < sp->timecnt * 4 + /* ats */ + if (nread - (p - u.buf) < + sp->timecnt * stored + /* ats */ sp->timecnt + /* types */ - sp->typecnt * (4 + 2) + /* ttinfos */ + sp->typecnt * 6 + /* ttinfos */ sp->charcnt + /* chars */ - sp->leapcnt * (4 + 4) + /* lsinfos */ + sp->leapcnt * (stored + 4) + /* lsinfos */ ttisstdcnt + /* ttisstds */ ttisgmtcnt) /* ttisgmts */ return -1; for (i = 0; i < sp->timecnt; ++i) { - sp->ats[i] = detzcode(p); - p += 4; + sp->ats[i] = (stored == 4) ? + detzcode(p) : detzcode64(p); + p += stored; } for (i = 0; i < sp->timecnt; ++i) { sp->types[i] = (unsigned char) *p++; @@ -375,8 +447,9 @@ register struct state * const sp; register struct lsinfo * lsisp; lsisp = &sp->lsis[i]; - lsisp->ls_trans = detzcode(p); - p += 4; + lsisp->ls_trans = (stored == 4) ? + detzcode(p) : detzcode64(p); + p += stored; lsisp->ls_corr = detzcode(p); p += 4; } @@ -406,10 +479,127 @@ register struct state * const sp; return -1; } } + /* + ** Out-of-sort ats should mean we're running on a + ** signed time_t system but using a data file with + ** unsigned values (or vice versa). + */ + for (i = 0; i < sp->timecnt - 2; ++i) + if (sp->ats[i] > sp->ats[i + 1]) { + ++i; + if (TYPE_SIGNED(time_t)) { + /* + ** Ignore the end (easy). + */ + sp->timecnt = i; + } else { + /* + ** Ignore the beginning (harder). + */ + register int j; + + for (j = 0; j + i < sp->timecnt; ++j) { + sp->ats[j] = sp->ats[j + i]; + sp->types[j] = sp->types[j + i]; + } + sp->timecnt = j; + } + break; + } + /* + ** If this is an old file, we're done. + */ + if (u.tzhead.tzh_version[0] == '\0') + break; + nread -= p - u.buf; + for (i = 0; i < nread; ++i) + u.buf[i] = p[i]; + /* + ** If this is a narrow integer time_t system, we're done. + */ + if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t)) + break; + } + if (doextend && nread > 2 && + u.buf[0] == '\n' && u.buf[nread - 1] == '\n' && + sp->typecnt + 2 <= TZ_MAX_TYPES) { + struct state ts; + register int result; + + u.buf[nread - 1] = '\0'; + result = tzparse(&u.buf[1], &ts, FALSE); + if (result == 0 && ts.typecnt == 2 && + sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) { + for (i = 0; i < 2; ++i) + ts.ttis[i].tt_abbrind += + sp->charcnt; + for (i = 0; i < ts.charcnt; ++i) + sp->chars[sp->charcnt++] = + ts.chars[i]; + i = 0; + while (i < ts.timecnt && + ts.ats[i] <= + sp->ats[sp->timecnt - 1]) + ++i; + while (i < ts.timecnt && + sp->timecnt < TZ_MAX_TIMES) { + sp->ats[sp->timecnt] = + ts.ats[i]; + sp->types[sp->timecnt] = + sp->typecnt + + ts.types[i]; + ++sp->timecnt; + ++i; + } + sp->ttis[sp->typecnt++] = ts.ttis[0]; + sp->ttis[sp->typecnt++] = ts.ttis[1]; + } + } + sp->goback = sp->goahead = FALSE; + if (sp->timecnt > 1) { + for (i = 1; i < sp->timecnt; ++i) + if (typesequiv(sp, sp->types[i], sp->types[0]) && + differ_by_repeat(sp->ats[i], sp->ats[0])) { + sp->goback = TRUE; + break; + } + for (i = sp->timecnt - 2; i >= 0; --i) + if (typesequiv(sp, sp->types[sp->timecnt - 1], + sp->types[i]) && + differ_by_repeat(sp->ats[sp->timecnt - 1], + sp->ats[i])) { + sp->goahead = TRUE; + break; + } } return 0; } +static int +typesequiv(sp, a, b) +const struct state * const sp; +const int a; +const int b; +{ + register int result; + + if (sp == NULL || + a < 0 || a >= sp->typecnt || + b < 0 || b >= sp->typecnt) + result = FALSE; + else { + register const struct ttinfo * ap = &sp->ttis[a]; + register const struct ttinfo * bp = &sp->ttis[b]; + result = ap->tt_gmtoff == bp->tt_gmtoff && + ap->tt_isdst == bp->tt_isdst && + ap->tt_ttisstd == bp->tt_ttisstd && + ap->tt_ttisgmt == bp->tt_ttisgmt && + strcmp(&sp->chars[ap->tt_abbrind], + &sp->chars[bp->tt_abbrind]) == 0; + } + return result; +} + static const int mon_lengths[2][MONSPERYEAR] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } @@ -421,7 +611,7 @@ static const int year_lengths[2] = { /* ** Given a pointer into a time zone string, scan until a character that is not -** a valid character in a zone name is found. Return a pointer to that +** a valid character in a zone name is found. Return a pointer to that ** character. */ @@ -437,6 +627,25 @@ register const char * strp; return strp; } +/* +** Given a pointer into an extended time zone string, scan until the ending +** delimiter of the zone name is located. Return a pointer to the delimiter. +** +** As with getzname above, the legal character set is actually quite +** restricted, with other characters producing undefined results. +** We don't do any checking here; checking is done later in common-case code. +*/ + +static const char * +getqzname(register const char *strp, const int delim) +{ + register int c; + + while ((c = *strp) != '\0' && c != delim) + ++strp; + return strp; +} + /* ** Given a pointer into a time zone string, extract a number from that string. ** Check that the number is within a specified range; if it is not, return @@ -502,7 +711,7 @@ long * const secsp; *secsp += num * SECSPERMIN; if (*strp == ':') { ++strp; - /* `SECSPERMIN' allows for leap seconds. */ + /* `SECSPERMIN' allows for leap seconds. */ strp = getnum(strp, &num, 0, SECSPERMIN); if (strp == NULL) return NULL; @@ -541,7 +750,7 @@ long * const offsetp; /* ** Given a pointer into a time zone string, extract a rule in the form -** date[/time]. See POSIX section 8 for the format of "date" and "time". +** date[/time]. See POSIX section 8 for the format of "date" and "time". ** If a valid rule is not found, return NULL. ** Otherwise, return a pointer to the first character not part of the rule. */ @@ -660,7 +869,7 @@ const long offset; dow += DAYSPERWEEK; /* - ** "dow" is the day-of-week of the first day of the month. Get + ** "dow" is the day-of-week of the first day of the month. Get ** the day-of-month (zero-origin) of the first "dow" day of the ** month. */ @@ -683,7 +892,7 @@ const long offset; /* ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in - ** question. To get the Epoch-relative time of the specified local + ** question. To get the Epoch-relative time of the specified local ** time on that day, add the transition time and the current offset ** from UTC. */ @@ -721,25 +930,40 @@ const int lastditch; stdlen = (sizeof sp->chars) - 1; stdoffset = 0; } else { - name = getzname(name); - stdlen = name - stdname; - if (stdlen < 3) - return -1; + if (*name == '<') { + name++; + stdname = name; + name = getqzname(name, '>'); + if (*name != '>') + return (-1); + stdlen = name - stdname; + name++; + } else { + name = getzname(name); + stdlen = name - stdname; + } if (*name == '\0') return -1; name = getoffset(name, &stdoffset); if (name == NULL) return -1; } - load_result = tzload(TZDEFRULES, sp); + load_result = tzload(TZDEFRULES, sp, FALSE); if (load_result != 0) sp->leapcnt = 0; /* so, we're off a little */ if (*name != '\0') { - dstname = name; - name = getzname(name); - dstlen = name - dstname; /* length of DST zone name */ - if (dstlen < 3) - return -1; + if (*name == '<') { + dstname = ++name; + name = getqzname(name, '>'); + if (*name != '>') + return -1; + dstlen = name - dstname; + name++; + } else { + dstname = name; + name = getzname(name); + dstlen = name - dstname; /* length of DST zone name */ + } if (*name != '\0' && *name != ',' && *name != ';') { name = getoffset(name, &dstoffset); if (name == NULL) @@ -766,11 +990,8 @@ const int lastditch; return -1; sp->typecnt = 2; /* standard time and DST */ /* - ** Two transitions per year, from EPOCH_YEAR to 2037. + ** Two transitions per year, from EPOCH_YEAR forward. */ - sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1); - if (sp->timecnt > TZ_MAX_TIMES) - return -1; sp->ttis[0].tt_gmtoff = -dstoffset; sp->ttis[0].tt_isdst = 1; sp->ttis[0].tt_abbrind = stdlen + 1; @@ -780,7 +1001,12 @@ const int lastditch; atp = sp->ats; typep = sp->types; janfirst = 0; - for (year = EPOCH_YEAR; year <= 2037; ++year) { + sp->timecnt = 0; + for (year = EPOCH_YEAR; + sp->timecnt + 2 <= TZ_MAX_TIMES; + ++year) { + time_t newfirst; + starttime = transtime(janfirst, year, &start, stdoffset); endtime = transtime(janfirst, year, &end, @@ -796,8 +1022,13 @@ const int lastditch; *atp++ = endtime; *typep++ = 1; /* DST ends */ } - janfirst += year_lengths[isleap(year)] * + sp->timecnt += 2; + newfirst = janfirst; + newfirst += year_lengths[isleap(year)] * SECSPERDAY; + if (newfirst <= janfirst) + break; + janfirst = newfirst; } } else { register long theirstdoffset; @@ -912,7 +1143,7 @@ static void gmtload(sp) struct state * const sp; { - if (tzload(gmt, sp) != 0) + if (tzload(gmt, sp, TRUE) != 0) (void) tzparse(gmt, sp, TRUE); } @@ -924,7 +1155,7 @@ struct state * const sp; static #endif /* !defined STD_INSPIRED */ void -tzsetwall P((void)) +tzsetwall(void) { if (lcl_is_set < 0) return; @@ -939,13 +1170,13 @@ tzsetwall P((void)) } } #endif /* defined ALL_STATE */ - if (tzload((char *) NULL, lclptr) != 0) + if (tzload((char *) NULL, lclptr, TRUE) != 0) gmtload(lclptr); settzname(); } void -tzset P((void)) +tzset(void) { register const char * name; @@ -981,7 +1212,7 @@ tzset P((void)) lclptr->ttis[0].tt_gmtoff = 0; lclptr->ttis[0].tt_abbrind = 0; (void) strcpy(lclptr->chars, gmt); - } else if (tzload(name, lclptr) != 0) + } else if (tzload(name, lclptr, TRUE) != 0) if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) (void) gmtload(lclptr); settzname(); @@ -990,14 +1221,14 @@ tzset P((void)) /* ** The easy way to behave "as if no library function calls" localtime ** is to not call it--so we drop its guts into "localsub", which can be -** freely called. (And no, the PANS doesn't require the above behavior-- +** freely called. (And no, the PANS doesn't require the above behavior-- ** but it *is* desirable.) ** ** The unused offset argument is for the benefit of mktime variants. */ /*ARGSUSED*/ -static void +static struct tm * localsub(timep, offset, tmp) const time_t * const timep; const long offset; @@ -1006,15 +1237,53 @@ struct tm * const tmp; register struct state * sp; register const struct ttinfo * ttisp; register int i; + register struct tm * result; const time_t t = *timep; sp = lclptr; #ifdef ALL_STATE - if (sp == NULL) { - gmtsub(timep, offset, tmp); - return; - } + if (sp == NULL) + return gmtsub(timep, offset, tmp); #endif /* defined ALL_STATE */ + if ((sp->goback && t < sp->ats[0]) || + (sp->goahead && t > sp->ats[sp->timecnt - 1])) { + time_t newt = t; + register time_t seconds; + register time_t tcycles; + register int_fast64_t icycles; + + if (t < sp->ats[0]) + seconds = sp->ats[0] - t; + else seconds = t - sp->ats[sp->timecnt - 1]; + --seconds; + tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR; + ++tcycles; + icycles = tcycles; + if (tcycles - icycles >= 1 || icycles - tcycles >= 1) + return NULL; + seconds = icycles; + seconds *= YEARSPERREPEAT; + seconds *= AVGSECSPERYEAR; + if (t < sp->ats[0]) + newt += seconds; + else newt -= seconds; + if (newt < sp->ats[0] || + newt > sp->ats[sp->timecnt - 1]) + return NULL; /* "cannot happen" */ + result = localsub(&newt, offset, tmp); + if (result == tmp) { + register time_t newy; + + newy = tmp->tm_year; + if (t < sp->ats[0]) + newy -= icycles * YEARSPERREPEAT; + else newy += icycles * YEARSPERREPEAT; + tmp->tm_year = newy; + if (tmp->tm_year != newy) + return NULL; + } + return result; + } if (sp->timecnt == 0 || t < sp->ats[0]) { i = 0; while (sp->ttis[i].tt_isdst) @@ -1023,10 +1292,17 @@ struct tm * const tmp; break; } } else { - for (i = 1; i < sp->timecnt; ++i) - if (t < sp->ats[i]) - break; - i = sp->types[i - 1]; + register int lo = 1; + register int hi = sp->timecnt; + + while (lo < hi) { + register int mid = (lo + hi) >> 1; + + if (t < sp->ats[mid]) + hi = mid; + else lo = mid + 1; + } + i = (int) sp->types[lo - 1]; } ttisp = &sp->ttis[i]; /* @@ -1035,12 +1311,13 @@ struct tm * const tmp; ** t += ttisp->tt_gmtoff; ** timesub(&t, 0L, sp, tmp); */ - timesub(&t, ttisp->tt_gmtoff, sp, tmp); + result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); tmp->tm_isdst = ttisp->tt_isdst; tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; #ifdef TM_ZONE tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; #endif /* defined TM_ZONE */ + return result; } struct tm * @@ -1048,8 +1325,7 @@ localtime(timep) const time_t * const timep; { tzset(); - localsub(timep, 0L, &tm); - return &tm; + return localsub(timep, 0L, &tm); } /* @@ -1057,24 +1333,25 @@ const time_t * const timep; */ struct tm * -localtime_r(timep, tm) +localtime_r(timep, tmp) const time_t * const timep; -struct tm * tm; +struct tm * tmp; { - localsub(timep, 0L, tm); - return tm; + return localsub(timep, 0L, tmp); } /* ** gmtsub is to gmtime as localsub is to localtime. */ -static void +static struct tm * gmtsub(timep, offset, tmp) const time_t * const timep; const long offset; struct tm * const tmp; { + register struct tm * result; + if (!gmt_is_set) { gmt_is_set = TRUE; #ifdef ALL_STATE @@ -1083,7 +1360,7 @@ struct tm * const tmp; #endif /* defined ALL_STATE */ gmtload(gmtptr); } - timesub(timep, offset, gmtptr, tmp); + result = timesub(timep, offset, gmtptr, tmp); #ifdef TM_ZONE /* ** Could get fancy here and deliver something such as @@ -1103,14 +1380,14 @@ struct tm * const tmp; #endif /* State Farm */ } #endif /* defined TM_ZONE */ + return result; } struct tm * gmtime(timep) const time_t * const timep; { - gmtsub(timep, 0L, &tm); - return &tm; + return gmtsub(timep, 0L, &tm); } /* @@ -1118,12 +1395,11 @@ const time_t * const timep; */ struct tm * -gmtime_r(timep, tm) +gmtime_r(timep, tmp) const time_t * const timep; -struct tm * tm; +struct tm * tmp; { - gmtsub(timep, 0L, tm); - return tm; + return gmtsub(timep, 0L, tmp); } #ifdef STD_INSPIRED @@ -1133,13 +1409,25 @@ offtime(timep, offset) const time_t * const timep; const long offset; { - gmtsub(timep, offset, &tm); - return &tm; + return gmtsub(timep, offset, &tm); } #endif /* defined STD_INSPIRED */ -static void +/* +** Return the number of leap years through the end of the given year +** where, to make the math easy, the answer for year zero is defined as zero. +*/ + +static int +leaps_thru_end_of(y) +register const int y; +{ + return (y >= 0) ? (y / 4 - y / 100 + y / 400) : + -(leaps_thru_end_of(-(y + 1)) + 1); +} + +static struct tm * timesub(timep, offset, sp, tmp) const time_t * const timep; const long offset; @@ -1147,10 +1435,10 @@ register const struct state * const sp; register struct tm * const tmp; { register const struct lsinfo * lp; - register long days; + register time_t tdays; + register int idays; /* unsigned would be so 2003 */ register long rem; - register int y; - register int yleap; + int y; register const int * ip; register long corr; register int hit; @@ -1184,60 +1472,93 @@ register struct tm * const tmp; break; } } - days = *timep / SECSPERDAY; - rem = *timep % SECSPERDAY; -#ifdef mc68k - if (*timep == 0x80000000) { - /* - ** A 3B1 muffs the division on the most negative number. - */ - days = -24855; - rem = -11648; + y = EPOCH_YEAR; + tdays = *timep / SECSPERDAY; + rem = *timep - tdays * SECSPERDAY; + while (tdays < 0 || tdays >= year_lengths[isleap(y)]) { + int newy; + register time_t tdelta; + register int idelta; + register int leapdays; + + tdelta = tdays / DAYSPERLYEAR; + idelta = tdelta; + if (tdelta - idelta >= 1 || idelta - tdelta >= 1) + return NULL; + if (idelta == 0) + idelta = (tdays < 0) ? -1 : 1; + newy = y; + if (increment_overflow(&newy, idelta)) + return NULL; + leapdays = leaps_thru_end_of(newy - 1) - + leaps_thru_end_of(y - 1); + tdays -= ((time_t) newy - y) * DAYSPERNYEAR; + tdays -= leapdays; + y = newy; } -#endif /* defined mc68k */ - rem += (offset - corr); + { + register long seconds; + + seconds = tdays * SECSPERDAY + 0.5; + tdays = seconds / SECSPERDAY; + rem += seconds - tdays * SECSPERDAY; + } + /* + ** Given the range, we can now fearlessly cast... + */ + idays = tdays; + rem += offset - corr; while (rem < 0) { rem += SECSPERDAY; - --days; + --idays; } while (rem >= SECSPERDAY) { rem -= SECSPERDAY; - ++days; + ++idays; } + while (idays < 0) { + if (increment_overflow(&y, -1)) + return NULL; + idays += year_lengths[isleap(y)]; + } + while (idays >= year_lengths[isleap(y)]) { + idays -= year_lengths[isleap(y)]; + if (increment_overflow(&y, 1)) + return NULL; + } + tmp->tm_year = y; + if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) + return NULL; + tmp->tm_yday = idays; + /* + ** The "extra" mods below avoid overflow problems. + */ + tmp->tm_wday = EPOCH_WDAY + + ((y - EPOCH_YEAR) % DAYSPERWEEK) * + (DAYSPERNYEAR % DAYSPERWEEK) + + leaps_thru_end_of(y - 1) - + leaps_thru_end_of(EPOCH_YEAR - 1) + + idays; + tmp->tm_wday %= DAYSPERWEEK; + if (tmp->tm_wday < 0) + tmp->tm_wday += DAYSPERWEEK; tmp->tm_hour = (int) (rem / SECSPERHOUR); - rem = rem % SECSPERHOUR; + rem %= SECSPERHOUR; tmp->tm_min = (int) (rem / SECSPERMIN); /* ** A positive leap second requires a special - ** representation. This uses "... ??:59:60" et seq. + ** representation. This uses "... ??:59:60" et seq. */ tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; - tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK); - if (tmp->tm_wday < 0) - tmp->tm_wday += DAYSPERWEEK; - y = EPOCH_YEAR; -#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) - while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) { - register int newy; - - newy = y + days / DAYSPERNYEAR; - if (days < 0) - --newy; - days -= (newy - y) * DAYSPERNYEAR + - LEAPS_THRU_END_OF(newy - 1) - - LEAPS_THRU_END_OF(y - 1); - y = newy; - } - tmp->tm_year = y - TM_YEAR_BASE; - tmp->tm_yday = (int) days; - ip = mon_lengths[yleap]; - for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon)) - days = days - (long) ip[tmp->tm_mon]; - tmp->tm_mday = (int) (days + 1); + ip = mon_lengths[isleap(y)]; + for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) + idays -= ip[tmp->tm_mon]; + tmp->tm_mday = (int) (idays + 1); tmp->tm_isdst = 0; #ifdef TM_GMTOFF tmp->TM_GMTOFF = offset; #endif /* defined TM_GMTOFF */ + return tmp; } char * @@ -1247,7 +1568,7 @@ const time_t * const timep; /* ** Section 4.12.3.2 of X3.159-1989 requires that ** The ctime function converts the calendar time pointed to by timer -** to local time in the form of a string. It is equivalent to +** to local time in the form of a string. It is equivalent to ** asctime(localtime(timer)) */ return asctime(localtime(timep)); @@ -1258,17 +1579,16 @@ ctime_r(timep, buf) const time_t * const timep; char * buf; { - struct tm tm; + struct tm mytm; - return asctime_r(localtime_r(timep, &tm), buf); + return asctime_r(localtime_r(timep, &mytm), buf); } /* ** Adapted from code provided by Robert Elz, who writes: ** The "best" way to do mktime I think is based on an idea of Bob ** Kridle's (so its said...) from a long time ago. -** [kridle@xinet.com as of 1996-01-16.] -** It does a binary search of the time_t space. Since time_t's are +** It does a binary search of the time_t space. Since time_t's are ** just 32 bits, its a max of 32 iterations (even at 64 bits it ** would still be very reasonable). */ @@ -1278,7 +1598,7 @@ char * buf; #endif /* !defined WRONG */ /* -** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com). +** Simplified normalize logic courtesy Paul Eggert. */ static int @@ -1293,6 +1613,18 @@ int delta; return (*number < number0) != (delta < 0); } +static int +long_increment_overflow(number, delta) +long * number; +int delta; +{ + long number0; + + number0 = *number; + *number += delta; + return (*number < number0) != (delta < 0); +} + static int normalize_overflow(tensptr, unitsptr, base) int * const tensptr; @@ -1308,6 +1640,21 @@ const int base; return increment_overflow(tensptr, tensdelta); } +static int +long_normalize_overflow(tensptr, unitsptr, base) +long * const tensptr; +int * const unitsptr; +const int base; +{ + register int tensdelta; + + tensdelta = (*unitsptr >= 0) ? + (*unitsptr / base) : + (-1 - (-1 - *unitsptr) / base); + *unitsptr -= tensdelta * base; + return long_increment_overflow(tensptr, tensdelta); +} + static int tmcomp(atmp, btmp) register const struct tm * const atmp; @@ -1327,16 +1674,19 @@ register const struct tm * const btmp; static time_t time2sub(tmp, funcp, offset, okayp, do_norm_secs) struct tm * const tmp; -void (* const funcp) P((const time_t*, long, struct tm*)); +struct tm * (* const funcp)(const time_t*, long, struct tm*); const long offset; int * const okayp; const int do_norm_secs; { register const struct state * sp; register int dir; - register int bits; - register int i, j ; + register int i, j; register int saved_seconds; + register long li; + register time_t lo; + register time_t hi; + long y; time_t newt; time_t t; struct tm yourtm, mytm; @@ -1352,42 +1702,46 @@ const int do_norm_secs; return WRONG; if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) return WRONG; - if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR)) + y = yourtm.tm_year; + if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR)) return WRONG; /* - ** Turn yourtm.tm_year into an actual year number for now. + ** Turn y into an actual year number for now. ** It is converted back to an offset from TM_YEAR_BASE later. */ - if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE)) + if (long_increment_overflow(&y, TM_YEAR_BASE)) return WRONG; while (yourtm.tm_mday <= 0) { - if (increment_overflow(&yourtm.tm_year, -1)) + if (long_increment_overflow(&y, -1)) return WRONG; - i = yourtm.tm_year + (1 < yourtm.tm_mon); - yourtm.tm_mday += year_lengths[isleap(i)]; + li = y + (1 < yourtm.tm_mon); + yourtm.tm_mday += year_lengths[isleap(li)]; } while (yourtm.tm_mday > DAYSPERLYEAR) { - i = yourtm.tm_year + (1 < yourtm.tm_mon); - yourtm.tm_mday -= year_lengths[isleap(i)]; - if (increment_overflow(&yourtm.tm_year, 1)) + li = y + (1 < yourtm.tm_mon); + yourtm.tm_mday -= year_lengths[isleap(li)]; + if (long_increment_overflow(&y, 1)) return WRONG; } for ( ; ; ) { - i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon]; + i = mon_lengths[isleap(y)][yourtm.tm_mon]; if (yourtm.tm_mday <= i) break; yourtm.tm_mday -= i; if (++yourtm.tm_mon >= MONSPERYEAR) { yourtm.tm_mon = 0; - if (increment_overflow(&yourtm.tm_year, 1)) + if (long_increment_overflow(&y, 1)) return WRONG; } } - if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE)) + if (long_increment_overflow(&y, -TM_YEAR_BASE)) + return WRONG; + yourtm.tm_year = y; + if (yourtm.tm_year != y) return WRONG; if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) saved_seconds = 0; - else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) { + else if (y + TM_YEAR_BASE < EPOCH_YEAR) { /* ** We can't set tm_sec to 0, because that might push the ** time below the minimum representable time. @@ -1405,27 +1759,53 @@ const int do_norm_secs; yourtm.tm_sec = 0; } /* - ** Divide the search space in half - ** (this works whether time_t is signed or unsigned). + ** Do a binary search (this works whatever time_t's type is). */ - bits = TYPE_BIT(time_t) - 1; - /* - ** If time_t is signed, then 0 is just above the median, - ** assuming two's complement arithmetic. - ** If time_t is unsigned, then (1 << bits) is just above the median. - */ - t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits); + if (!TYPE_SIGNED(time_t)) { + lo = 0; + hi = lo - 1; + } else if (!TYPE_INTEGRAL(time_t)) { + if (sizeof(time_t) > sizeof(float)) + hi = (time_t) DBL_MAX; + else hi = (time_t) FLT_MAX; + lo = -hi; + } else { + lo = 1; + for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i) + lo *= 2; + hi = -(lo + 1); + } for ( ; ; ) { - (*funcp)(&t, offset, &mytm); - dir = tmcomp(&mytm, &yourtm); + t = lo / 2 + hi / 2; + if (t < lo) + t = lo; + else if (t > hi) + t = hi; + if ((*funcp)(&t, offset, &mytm) == NULL) { + /* + ** Assume that t is too extreme to be represented in + ** a struct tm; arrange things so that it is less + ** extreme on the next pass. + */ + dir = (t > 0) ? 1 : -1; + } else dir = tmcomp(&mytm, &yourtm); if (dir != 0) { - if (bits-- < 0) + if (t == lo) { + ++t; + if (t <= lo) + return WRONG; + ++lo; + } else if (t == hi) { + --t; + if (t >= hi) + return WRONG; + --hi; + } + if (lo > hi) return WRONG; - if (bits < 0) - --t; /* may be needed if new t is minimal */ - else if (dir > 0) - t -= ((time_t) 1) << bits; - else t += ((time_t) 1) << bits; + if (dir > 0) + hi = t; + else lo = t; continue; } if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) @@ -1436,12 +1816,8 @@ const int do_norm_secs; ** It's okay to guess wrong since the guess ** gets checked. */ - /* - ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. - */ sp = (const struct state *) - (((void *) funcp == (void *) localsub) ? - lclptr : gmtptr); + ((funcp == localsub) ? lclptr : gmtptr); #ifdef ALL_STATE if (sp == NULL) return WRONG; @@ -1454,7 +1830,8 @@ const int do_norm_secs; continue; newt = t + sp->ttis[j].tt_gmtoff - sp->ttis[i].tt_gmtoff; - (*funcp)(&newt, offset, &mytm); + if ((*funcp)(&newt, offset, &mytm) == NULL) + continue; if (tmcomp(&mytm, &yourtm) != 0) continue; if (mytm.tm_isdst != yourtm.tm_isdst) @@ -1473,15 +1850,15 @@ const int do_norm_secs; if ((newt < t) != (saved_seconds < 0)) return WRONG; t = newt; - (*funcp)(&t, offset, tmp); - *okayp = TRUE; + if ((*funcp)(&t, offset, tmp)) + *okayp = TRUE; return t; } static time_t time2(tmp, funcp, offset, okayp) struct tm * const tmp; -void (* const funcp) P((const time_t*, long, struct tm*)); +struct tm * (* const funcp)(const time_t*, long, struct tm*); const long offset; int * const okayp; { @@ -1499,7 +1876,7 @@ int * const okayp; static time_t time1(tmp, funcp, offset) struct tm * const tmp; -void (* const funcp) P((const time_t *, long, struct tm *)); +struct tm * (* const funcp)(const time_t *, long, struct tm *); const long offset; { register time_t t; @@ -1517,7 +1894,7 @@ const long offset; t = time2(tmp, funcp, offset, &okay); #ifdef PCTS /* - ** PCTS code courtesy Grant Sullivan (grant@osf.org). + ** PCTS code courtesy Grant Sullivan. */ if (okay) return t; @@ -1534,11 +1911,7 @@ const long offset; ** We try to divine the type they started from and adjust to the ** type they need. */ - /* - ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. - */ - sp = (const struct state *) (((void *) funcp == (void *) localsub) ? - lclptr : gmtptr); + sp = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr); #ifdef ALL_STATE if (sp == NULL) return WRONG; @@ -1680,7 +2053,7 @@ time_t t; tzset(); /* ** For a positive leap second hit, the result - ** is not unique. For a negative leap second + ** is not unique. For a negative leap second ** hit, the corresponding time doesn't exist, ** so we return an adjacent second. */ diff --git a/libc/stdtime/private.h b/libc/stdtime/private.h index c8f45486837f..008d468ac787 100644 --- a/libc/stdtime/private.h +++ b/libc/stdtime/private.h @@ -4,7 +4,7 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. */ /* @@ -21,10 +21,12 @@ #ifndef lint #ifndef NOID -static char privatehid[] = "@(#)private.h 7.53"; +static char privatehid[] = "@(#)private.h 8.6"; #endif /* !defined NOID */ #endif /* !defined lint */ +#define GRANDPARENTED "Local time zone must be set--see zic manual page" + /* ** Defaults for preprocessor symbols. ** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'. @@ -46,10 +48,6 @@ static char privatehid[] = "@(#)private.h 7.53"; #define HAVE_SETTIMEOFDAY 3 #endif /* !defined HAVE_SETTIMEOFDAY */ -#ifndef HAVE_STRERROR -#define HAVE_STRERROR 1 -#endif /* !defined HAVE_STRERROR */ - #ifndef HAVE_SYMLINK #define HAVE_SYMLINK 1 #endif /* !defined HAVE_SYMLINK */ @@ -87,17 +85,17 @@ static char privatehid[] = "@(#)private.h 7.53"; #include "stdio.h" #include "errno.h" #include "string.h" -#include "limits.h" /* for CHAR_BIT */ +#include "limits.h" /* for CHAR_BIT et al. */ #include "time.h" #include "stdlib.h" -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #include "libintl.h" -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ -#if HAVE_SYS_WAIT_H - 0 +#if HAVE_SYS_WAIT_H #include /* for WIFEXITED and WEXITSTATUS */ -#endif /* HAVE_SYS_WAIT_H - 0 */ +#endif /* HAVE_SYS_WAIT_H */ #ifndef WIFEXITED #define WIFEXITED(status) (((status) & 0xff) == 0) @@ -106,106 +104,82 @@ static char privatehid[] = "@(#)private.h 7.53"; #define WEXITSTATUS(status) (((status) >> 8) & 0xff) #endif /* !defined WEXITSTATUS */ -#if HAVE_UNISTD_H - 0 -#include "unistd.h" /* for F_OK and R_OK */ -#endif /* HAVE_UNISTD_H - 0 */ +#if HAVE_UNISTD_H +#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */ +#endif /* HAVE_UNISTD_H */ -#if !(HAVE_UNISTD_H - 0) #ifndef F_OK #define F_OK 0 #endif /* !defined F_OK */ #ifndef R_OK #define R_OK 4 #endif /* !defined R_OK */ -#endif /* !(HAVE_UNISTD_H - 0) */ -/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ +/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ #define is_digit(c) ((unsigned)(c) - '0' <= 9) +/* +** Define HAVE_STDINT_H's default value here, rather than at the +** start, since __GLIBC__'s value depends on previously-included +** files. +** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.) +*/ +#ifndef HAVE_STDINT_H +#define HAVE_STDINT_H \ + (199901 <= __STDC_VERSION__ || \ + 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__))) +#endif /* !defined HAVE_STDINT_H */ + +#if HAVE_STDINT_H +#include "stdint.h" +#endif /* !HAVE_STDINT_H */ + +#ifndef INT_FAST64_MAX +/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */ +#if defined LLONG_MAX || defined __LONG_LONG_MAX__ +typedef long long int_fast64_t; +#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#if (LONG_MAX >> 31) < 0xffffffff +Please use a compiler that supports a 64-bit integer type (or wider); +you may need to compile with "-DHAVE_STDINT_H". +#endif /* (LONG_MAX >> 31) < 0xffffffff */ +typedef long int_fast64_t; +#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#endif /* !defined INT_FAST64_MAX */ + +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif /* !defined INT32_MAX */ +#ifndef INT32_MIN +#define INT32_MIN (-1 - INT32_MAX) +#endif /* !defined INT32_MIN */ + /* ** Workarounds for compilers/systems. */ /* -** SunOS 4.1.1 cc lacks prototypes. -*/ - -#ifndef P -#ifdef __STDC__ -#define P(x) x -#endif /* defined __STDC__ */ -#ifndef __STDC__ -#define P(x) () -#endif /* !defined __STDC__ */ -#endif /* !defined P */ - -/* -** SunOS 4.1.1 headers lack EXIT_SUCCESS. -*/ - -#ifndef EXIT_SUCCESS -#define EXIT_SUCCESS 0 -#endif /* !defined EXIT_SUCCESS */ - -/* -** SunOS 4.1.1 headers lack EXIT_FAILURE. -*/ - -#ifndef EXIT_FAILURE -#define EXIT_FAILURE 1 -#endif /* !defined EXIT_FAILURE */ - -/* -** SunOS 4.1.1 headers lack FILENAME_MAX. -*/ - -#ifndef FILENAME_MAX - -#ifndef MAXPATHLEN -#ifdef unix -#include "sys/param.h" -#endif /* defined unix */ -#endif /* !defined MAXPATHLEN */ - -#ifdef MAXPATHLEN -#define FILENAME_MAX MAXPATHLEN -#endif /* defined MAXPATHLEN */ -#ifndef MAXPATHLEN -#define FILENAME_MAX 1024 /* Pure guesswork */ -#endif /* !defined MAXPATHLEN */ - -#endif /* !defined FILENAME_MAX */ - -/* -** SunOS 4.1.1 libraries lack remove. -*/ - -#ifndef remove -extern int unlink P((const char * filename)); -#define remove unlink -#endif /* !defined remove */ - -/* -** Some ancient errno.h implementations don't declare errno. -** But some newer errno.h implementations define it as a macro. +** Some time.h implementations don't declare asctime_r. +** Others might define it as a macro. ** Fix the former without affecting the latter. */ -#ifndef errno -extern int errno; -#endif /* !defined errno */ + +#ifndef asctime_r +extern char * asctime_r(struct tm const *, char *); +#endif /* ** Private function declarations. */ -char * icalloc P((int nelem, int elsize)); -char * icatalloc P((char * old, const char * new)); -char * icpyalloc P((const char * string)); -char * imalloc P((int n)); -void * irealloc P((void * pointer, int size)); -void icfree P((char * pointer)); -void ifree P((char * pointer)); -char * scheck P((const char *string, const char *format)); +char * icalloc(int nelem, int elsize); +char * icatalloc(char * old, const char * new); +char * icpyalloc(const char * string); +char * imalloc(int n); +void * irealloc(void * pointer, int size); +void icfree(char * pointer); +void ifree(char * pointer); +const char * scheck(const char * string, const char * format); /* ** Finally, some convenience items. @@ -227,6 +201,15 @@ char * scheck P((const char *string, const char *format)); #define TYPE_SIGNED(type) (((type) -1) < 0) #endif /* !defined TYPE_SIGNED */ +/* +** Since the definition of TYPE_INTEGRAL contains floating point numbers, +** it cannot be used in preprocessor directives. +*/ + +#ifndef TYPE_INTEGRAL +#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5) +#endif /* !defined TYPE_INTEGRAL */ + #ifndef INT_STRLEN_MAXIMUM /* ** 302 / 1000 is log10(2.0) rounded up. @@ -235,7 +218,8 @@ char * scheck P((const char *string, const char *format)); ** add one more for a minus sign if the type is signed. */ #define INT_STRLEN_MAXIMUM(type) \ - ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type)) + ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \ + 1 + TYPE_SIGNED(type)) #endif /* !defined INT_STRLEN_MAXIMUM */ /* @@ -269,11 +253,11 @@ char * scheck P((const char *string, const char *format)); */ #ifndef _ -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #define _(msgid) gettext(msgid) -#else /* !(HAVE_GETTEXT - 0) */ +#else /* !HAVE_GETTEXT */ #define _(msgid) msgid -#endif /* !(HAVE_GETTEXT - 0) */ +#endif /* !HAVE_GETTEXT */ #endif /* !defined _ */ #ifndef TZ_DOMAIN @@ -283,10 +267,30 @@ char * scheck P((const char *string, const char *format)); #if HAVE_INCOMPATIBLE_CTIME_R #undef asctime_r #undef ctime_r -char *asctime_r P((struct tm const *, char *)); -char *ctime_r P((time_t const *, char *)); +char *asctime_r(struct tm const *, char *); +char *ctime_r(time_t const *, char *); #endif /* HAVE_INCOMPATIBLE_CTIME_R */ +#ifndef YEARSPERREPEAT +#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ +#endif /* !defined YEARSPERREPEAT */ + +/* +** The Gregorian year averages 365.2425 days, which is 31556952 seconds. +*/ + +#ifndef AVGSECSPERYEAR +#define AVGSECSPERYEAR 31556952L +#endif /* !defined AVGSECSPERYEAR */ + +#ifndef SECSPERREPEAT +#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR) +#endif /* !defined SECSPERREPEAT */ + +#ifndef SECSPERREPEAT_BITS +#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */ +#endif /* !defined SECSPERREPEAT_BITS */ + /* ** UNIX was a registered trademark of The Open Group in 2003. */ diff --git a/libc/stdtime/strftime.c b/libc/stdtime/strftime.c index 365a42e12b88..d036d07690f6 100644 --- a/libc/stdtime/strftime.c +++ b/libc/stdtime/strftime.c @@ -1,6 +1,6 @@ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)strftime.c 7.64"; +static char elsieid[] = "@(#)strftime.c 8.3"; /* ** Based on the UCB version with the ID appearing below. ** This is ANSIish only when "multibyte character == plain character". @@ -19,7 +19,7 @@ static char elsieid[] = "@(#)strftime.c 7.64"; ** duplicated in all such forms and that any documentation, ** advertising materials, and other materials related to such ** distribution and use acknowledge that the software was developed -** by the University of California, Berkeley. The name of the +** by the University of California, Berkeley. The name of the ** University may not be used to endorse or promote products derived ** from this software without specific prior written permission. ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR @@ -53,7 +53,7 @@ struct lc_time_T { #ifdef LOCALE_HOME #include "sys/stat.h" static struct lc_time_T localebuf; -static struct lc_time_T * _loc P((void)); +static struct lc_time_T * _loc(void); #define Locale _loc() #endif /* defined LOCALE_HOME */ #ifndef LOCALE_HOME @@ -91,7 +91,7 @@ static const struct lc_time_T C_time_locale = { ** C99 requires this format. ** Previously this code used "%D %X", but we now conform to C99. ** Note that - ** "%a %b %d %H:%M:%S %Y" + ** "%a %b %d %H:%M:%S %Y" ** is used by Solaris 2.3. */ "%a %b %e %T %Y", @@ -106,11 +106,11 @@ static const struct lc_time_T C_time_locale = { "%a %b %e %H:%M:%S %Z %Y" }; -static char * _add P((const char *, char *, const char *)); -static char * _conv P((int, const char *, char *, const char *)); -static char * _fmt P((const char *, const struct tm *, char *, const char *, int *)); - -size_t strftime P((char *, size_t, const char *, const struct tm *)); +static char * _add(const char *, char *, const char *); +static char * _conv(int, const char *, char *, const char *); +static char * _fmt(const char *, const struct tm *, char *, const char *, + int *); +static char * _yconv(int, int, int, int, char *, const char *); extern char * tzname[]; @@ -118,7 +118,6 @@ extern char * tzname[]; #define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" #endif /* !defined YEAR_2000_NAME */ - #define IN_NONE 0 #define IN_SOME 1 #define IN_THIS 2 @@ -210,14 +209,14 @@ int * warnp; ** something completely different. ** (ado, 1993-05-24) */ - pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, - "%02d", pt, ptlim); + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0, + pt, ptlim); continue; case 'c': { int warn2 = IN_SOME; - pt = _fmt(Locale->c_fmt, t, pt, ptlim, warnp); + pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2); if (warn2 == IN_ALL) warn2 = IN_THIS; if (warn2 > *warnp) @@ -266,7 +265,7 @@ int * warnp; ** t->tm_hour % 12 : 12, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbins' - ** strftime version 3.0. That is, "%k" and + ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ @@ -286,7 +285,7 @@ int * warnp; ** _conv(t->tm_hour, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbin's - ** strftime version 3.0. That is, "%k" and + ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ @@ -361,7 +360,7 @@ int * warnp; case 'G': /* ISO 8601 year (four digits) */ case 'g': /* ISO 8601 year (two digits) */ /* -** From Arnold Robbins' strftime version 3.0: "the week number of the +** From Arnold Robbins' strftime version 3.0: "the week number of the ** year (the first Monday as the first day of week 1) as a decimal number ** (01-53)." ** (ado, 1993-05-24) @@ -374,17 +373,19 @@ int * warnp; ** might also contain days from the previous year and the week before week ** 01 of a year is the last week (52 or 53) of the previous year even if ** it contains days from the new year. A week starts with Monday (day 1) -** and ends with Sunday (day 7). For example, the first week of the year +** and ends with Sunday (day 7). For example, the first week of the year ** 1997 lasts from 1996-12-30 to 1997-01-05..." ** (ado, 1996-01-02) */ { int year; + int base; int yday; int wday; int w; - year = t->tm_year + TM_YEAR_BASE; + year = t->tm_year; + base = TM_YEAR_BASE; yday = t->tm_yday; wday = t->tm_wday; for ( ; ; ) { @@ -392,7 +393,7 @@ int * warnp; int bot; int top; - len = isleap(year) ? + len = isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; /* @@ -411,7 +412,7 @@ int * warnp; top += DAYSPERWEEK; top += len; if (yday >= top) { - ++year; + ++base; w = 1; break; } @@ -420,26 +421,26 @@ int * warnp; DAYSPERWEEK); break; } - --year; - yday += isleap(year) ? + --base; + yday += isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; } #ifdef XPG4_1994_04_09 - if ((w == 52 - && t->tm_mon == TM_JANUARY) - || (w == 1 - && t->tm_mon == TM_DECEMBER)) - w = 53; + if ((w == 52 && + t->tm_mon == TM_JANUARY) || + (w == 1 && + t->tm_mon == TM_DECEMBER)) + w = 53; #endif /* defined XPG4_1994_04_09 */ if (*format == 'V') pt = _conv(w, "%02d", pt, ptlim); else if (*format == 'g') { *warnp = IN_ALL; - pt = _conv(year % 100, "%02d", + pt = _yconv(year, base, 0, 1, pt, ptlim); - } else pt = _conv(year, "%04d", + } else pt = _yconv(year, base, 1, 1, pt, ptlim); } continue; @@ -477,11 +478,11 @@ int * warnp; continue; case 'y': *warnp = IN_ALL; - pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, - "%02d", pt, ptlim); + pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, + pt, ptlim); continue; case 'Y': - pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, pt, ptlim); continue; case 'Z': @@ -512,12 +513,12 @@ int * warnp; /* ** C99 says that the UTC offset must ** be computed by looking only at - ** tm_isdst. This requirement is + ** tm_isdst. This requirement is ** incorrect, since it means the code ** must rely on magic (in this case ** altzone and timezone), and the ** magic might not have the correct - ** offset. Doing things correctly is + ** offset. Doing things correctly is ** tricky and requires disobeying C99; ** see GNU C strftime for details. ** For now, punt and conform to the @@ -546,9 +547,10 @@ int * warnp; diff = -diff; } else sign = "+"; pt = _add(sign, pt, ptlim); - diff /= 60; - pt = _conv((diff/60)*100 + diff%60, - "%04d", pt, ptlim); + diff /= SECSPERMIN; + diff = (diff / MINSPERHOUR) * 100 + + (diff % MINSPERHOUR); + pt = _conv(diff, "%04d", pt, ptlim); } continue; case '+': @@ -558,7 +560,7 @@ int * warnp; case '%': /* ** X311J/88-090 (4.12.3.5): if conversion char is - ** undefined, behavior is undefined. Print out the + ** undefined, behavior is undefined. Print out the ** character itself as printf(3) also does. */ default: @@ -596,9 +598,50 @@ const char * const ptlim; return pt; } +/* +** POSIX and the C Standard are unclear or inconsistent about +** what %C and %y do if the year is negative or exceeds 9999. +** Use the convention that %C concatenated with %y yields the +** same output as %Y, and that %Y contains at least 4 bytes, +** with more only if necessary. +*/ + +static char * +_yconv(a, b, convert_top, convert_yy, pt, ptlim) +const int a; +const int b; +const int convert_top; +const int convert_yy; +char * pt; +const char * const ptlim; +{ + register int lead; + register int trail; + +#define DIVISOR 100 + trail = a % DIVISOR + b % DIVISOR; + lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR; + trail %= DIVISOR; + if (trail < 0 && lead > 0) { + trail += DIVISOR; + --lead; + } else if (lead < 0 && trail > 0) { + trail -= DIVISOR; + ++lead; + } + if (convert_top) { + if (lead == 0 && trail < 0) + pt = _add("-0", pt, ptlim); + else pt = _conv(lead, "%02d", pt, ptlim); + } + if (convert_yy) + pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim); + return pt; +} + #ifdef LOCALE_HOME static struct lc_time_T * -_loc P((void)) +_loc(void) { static const char locale_home[] = LOCALE_HOME; static const char lc_time[] = "LC_TIME"; @@ -640,7 +683,7 @@ _loc P((void)) ** Slurp the locale file into the cache. */ namesize = strlen(name) + 1; - if (sizeof filename < + if (sizeof filename < ((sizeof locale_home) + namesize + (sizeof lc_time))) goto no_locale; oldsun = 0; @@ -663,7 +706,7 @@ _loc P((void)) goto bad_locale; bufsize = namesize + st.st_size; locale_buf = NULL; - lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize); + lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize); if (lbuf == NULL) goto bad_locale; (void) strcpy(lbuf, name); diff --git a/libc/stdtime/time2posix.3 b/libc/stdtime/time2posix.3 new file mode 100644 index 000000000000..96959c642ed5 --- /dev/null +++ b/libc/stdtime/time2posix.3 @@ -0,0 +1,121 @@ +.TH TIME2POSIX 3 +.SH NAME +time2posix, posix2time \- convert seconds since the Epoch +.SH SYNOPSIS +.nf +.B #include +.B #include +.PP +.B time_t time2posix(t) +.B time_t t +.PP +.B time_t posix2time(t) +.B time_t t +.PP +.B cc ... -ltz +.fi +.SH DESCRIPTION +IEEE Standard 1003.1 +(POSIX) +legislates that a time_t value of +536457599 shall correspond to "Wed Dec 31 23:59:59 UTC 1986." +This effectively implies that POSIX time_t's cannot include leap +seconds and, +therefore, +that the system time must be adjusted as each leap occurs. +.PP +If the time package is configured with leap-second support +enabled, +however, +no such adjustment is needed and +time_t values continue to increase over leap events +(as a true `seconds since...' value). +This means that these values will differ from those required by POSIX +by the net number of leap seconds inserted since the Epoch. +.PP +Typically this is not a problem as the type time_t is intended +to be +(mostly) +opaque\(emtime_t values should only be obtained-from and +passed-to functions such as +.IR time(2) , +.IR localtime(3) , +.IR mktime(3) , +and +.IR difftime(3) . +However, +POSIX gives an arithmetic +expression for directly computing a time_t value from a given date/time, +and the same relationship is assumed by some +(usually older) +applications. +Any programs creating/dissecting time_t's +using such a relationship will typically not handle intervals +over leap seconds correctly. +.PP +The +.I time2posix +and +.I posix2time +functions are provided to address this time_t mismatch by converting +between local time_t values and their POSIX equivalents. +This is done by accounting for the number of time-base changes that +would have taken place on a POSIX system as leap seconds were inserted +or deleted. +These converted values can then be used in lieu of correcting the older +applications, +or when communicating with POSIX-compliant systems. +.PP +.I Time2posix +is single-valued. +That is, +every local time_t +corresponds to a single POSIX time_t. +.I Posix2time +is less well-behaved: +for a positive leap second hit the result is not unique, +and for a negative leap second hit the corresponding +POSIX time_t doesn't exist so an adjacent value is returned. +Both of these are good indicators of the inferiority of the +POSIX representation. +.PP +The following table summarizes the relationship between a time +T and it's conversion to, +and back from, +the POSIX representation over the leap second inserted at the end of June, +1993. +.nf +.ta \w'93/06/30 'u +\w'23:59:59 'u +\w'A+0 'u +\w'X=time2posix(T) 'u +DATE TIME T X=time2posix(T) posix2time(X) +93/06/30 23:59:59 A+0 B+0 A+0 +93/06/30 23:59:60 A+1 B+1 A+1 or A+2 +93/07/01 00:00:00 A+2 B+1 A+1 or A+2 +93/07/01 00:00:01 A+3 B+2 A+3 + +A leap second deletion would look like... + +DATE TIME T X=time2posix(T) posix2time(X) +??/06/30 23:59:58 A+0 B+0 A+0 +??/07/01 00:00:00 A+1 B+2 A+1 +??/07/01 00:00:01 A+2 B+3 A+2 +.sp +.ce + [Note: posix2time(B+1) => A+0 or A+1] +.fi +.PP +If leap-second support is not enabled, +local time_t's and +POSIX time_t's are equivalent, +and both +.I time2posix +and +.I posix2time +degenerate to the identity function. +.SH SEE ALSO +difftime(3), +localtime(3), +mktime(3), +time(2) +.\" @(#)time2posix.3 8.1 +.\" This file is in the public domain, so clarified as of +.\" 1996-06-05 by Arthur David Olson. diff --git a/libc/stdtime/tzfile.5 b/libc/stdtime/tzfile.5 new file mode 100644 index 000000000000..6b8768cc9fc5 --- /dev/null +++ b/libc/stdtime/tzfile.5 @@ -0,0 +1,152 @@ +.TH TZFILE 5 +.SH NAME +tzfile \- time zone information +.SH SYNOPSIS +.B +#include +.SH DESCRIPTION +The time zone information files used by +.IR tzset (3) +begin with the magic characters "TZif" to identify then as +time zone information files, +followed by a character identifying the version of the file's format +(as of 2005, either an ASCII NUL or a '2') +followed by fifteen bytes containing zeroes reserved for future use, +followed by six four-byte values of type +.BR long , +written in a ``standard'' byte order +(the high-order byte of the value is written first). +These values are, +in order: +.TP +.I tzh_ttisgmtcnt +The number of UTC/local indicators stored in the file. +.TP +.I tzh_ttisstdcnt +The number of standard/wall indicators stored in the file. +.TP +.I tzh_leapcnt +The number of leap seconds for which data is stored in the file. +.TP +.I tzh_timecnt +The number of "transition times" for which data is stored +in the file. +.TP +.I tzh_typecnt +The number of "local time types" for which data is stored +in the file (must not be zero). +.TP +.I tzh_charcnt +The number of characters of "time zone abbreviation strings" +stored in the file. +.PP +The above header is followed by +.I tzh_timecnt +four-byte values of type +.BR long , +sorted in ascending order. +These values are written in ``standard'' byte order. +Each is used as a transition time (as returned by +.IR time (2)) +at which the rules for computing local time change. +Next come +.I tzh_timecnt +one-byte values of type +.BR "unsigned char" ; +each one tells which of the different types of ``local time'' types +described in the file is associated with the same-indexed transition time. +These values serve as indices into an array of +.I ttinfo +structures (with +.I tzh_typecnt +entries) that appears next in the file; +these structures are defined as follows: +.in +.5i +.sp +.nf +.ta .5i +\w'unsigned int\0\0'u +struct ttinfo { + long tt_gmtoff; + int tt_isdst; + unsigned int tt_abbrind; +}; +.in -.5i +.fi +.sp +Each structure is written as a four-byte value for +.I tt_gmtoff +of type +.BR long , +in a standard byte order, followed by a one-byte value for +.I tt_isdst +and a one-byte value for +.IR tt_abbrind . +In each structure, +.I tt_gmtoff +gives the number of seconds to be added to UTC, +.I tt_isdst +tells whether +.I tm_isdst +should be set by +.I localtime (3) +and +.I tt_abbrind +serves as an index into the array of time zone abbreviation characters +that follow the +.I ttinfo +structure(s) in the file. +.PP +Then there are +.I tzh_leapcnt +pairs of four-byte values, written in standard byte order; +the first value of each pair gives the time +(as returned by +.IR time(2)) +at which a leap second occurs; +the second gives the +.I total +number of leap seconds to be applied after the given time. +The pairs of values are sorted in ascending order by time. +.PP +Then there are +.I tzh_ttisstdcnt +standard/wall indicators, each stored as a one-byte value; +they tell whether the transition times associated with local time types +were specified as standard time or wall clock time, +and are used when a time zone file is used in handling POSIX-style +time zone environment variables. +.PP +Finally there are +.I tzh_ttisgmtcnt +UTC/local indicators, each stored as a one-byte value; +they tell whether the transition times associated with local time types +were specified as UTC or local time, +and are used when a time zone file is used in handling POSIX-style +time zone environment variables. +.PP +.I Localtime +uses the first standard-time +.I ttinfo +structure in the file +(or simply the first +.I ttinfo +structure in the absence of a standard-time structure) +if either +.I tzh_timecnt +is zero or the time argument is less than the first transition time recorded +in the file. +.PP +For version-2-format time zone files, +the above header and data is followed by a second header and data, +identical in format except that +eight bytes are used for each transition time or leap second time. +After the second header and data comes a newline-enclosed, +POSIX-TZ-environment-variable-style string for use in handling instants +after the last transition time stored in the file +(with nothing between the newlines if there is no POSIX representation for +such instants). +.SH SEE ALSO +newctime(3) +.\" @(#)tzfile.5 8.2 +.\" This file is in the public domain, so clarified as of +.\" 1996-06-05 by Arthur David Olson. diff --git a/libc/stdtime/tzfile.h b/libc/stdtime/tzfile.h index 0921c3c3396e..3a9eee305a53 100644 --- a/libc/stdtime/tzfile.h +++ b/libc/stdtime/tzfile.h @@ -4,7 +4,7 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. */ /* @@ -21,7 +21,7 @@ #ifndef lint #ifndef NOID -static char tzfilehid[] = "@(#)tzfile.h 7.14"; +static char tzfilehid[] = "@(#)tzfile.h 8.1"; #endif /* !defined NOID */ #endif /* !defined lint */ @@ -48,8 +48,9 @@ static char tzfilehid[] = "@(#)tzfile.h 7.14"; #define TZ_MAGIC "TZif" struct tzhead { - char tzh_magic[4]; /* TZ_MAGIC */ - char tzh_reserved[16]; /* reserved for future use */ + char tzh_magic[4]; /* TZ_MAGIC */ + char tzh_version[1]; /* '\0' or '2' as of 2005 */ + char tzh_reserved[15]; /* reserved--must be zero */ char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ char tzh_leapcnt[4]; /* coded number of leap seconds */ @@ -83,19 +84,23 @@ struct tzhead { ** assumed to be local time */ +/* +** If tzh_version is '2' or greater, the above is followed by a second instance +** of tzhead and a second instance of the data in which each coded transition +** time uses 8 rather than 4 chars, +** then a POSIX-TZ-environment-variable-style string for use in handling +** instants after the last transition time stored in the file +** (with nothing between the newlines if there is no POSIX representation for +** such instants). +*/ + /* ** In the current implementation, "tzset()" refuses to deal with files that ** exceed any of the limits below. */ #ifndef TZ_MAX_TIMES -/* -** The TZ_MAX_TIMES value below is enough to handle a bit more than a -** year's worth of solar time (corrected daily to the nearest second) or -** 138 years of Pacific Presidential Election time -** (where there are three time zone transitions every fourth year). -*/ -#define TZ_MAX_TIMES 370 +#define TZ_MAX_TIMES 1200 #endif /* !defined TZ_MAX_TIMES */ #ifndef TZ_MAX_TYPES @@ -105,7 +110,7 @@ struct tzhead { #ifdef NOSOLAR /* ** Must be at least 14 for Europe/Riga as of Jan 12 1995, -** as noted by Earl Chew . +** as noted by Earl Chew. */ #define TZ_MAX_TYPES 20 /* Maximum number of local time types */ #endif /* !defined NOSOLAR */ @@ -156,33 +161,20 @@ struct tzhead { #define EPOCH_YEAR 1970 #define EPOCH_WDAY TM_THURSDAY -/* -** Accurate only for the past couple of centuries; -** that will probably do. -*/ - #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) -#ifndef USG - /* -** Use of the underscored variants may cause problems if you move your code to -** certain System-V-based systems; for maximum portability, use the -** underscore-free variants. The underscored variants are provided for -** backward compatibility only; they may disappear from future versions of -** this file. +** Since everything in isleap is modulo 400 (or a factor of 400), we know that +** isleap(y) == isleap(y % 400) +** and so +** isleap(a + b) == isleap((a + b) % 400) +** or +** isleap(a + b) == isleap(a % 400 + b % 400) +** This is true even if % means modulo rather than Fortran remainder +** (which is allowed by C89 but not C99). +** We use this to avoid addition overflow problems. */ -#define SECS_PER_MIN SECSPERMIN -#define MINS_PER_HOUR MINSPERHOUR -#define HOURS_PER_DAY HOURSPERDAY -#define DAYS_PER_WEEK DAYSPERWEEK -#define DAYS_PER_NYEAR DAYSPERNYEAR -#define DAYS_PER_LYEAR DAYSPERLYEAR -#define SECS_PER_HOUR SECSPERHOUR -#define SECS_PER_DAY SECSPERDAY -#define MONS_PER_YEAR MONSPERYEAR - -#endif /* !defined USG */ +#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) #endif /* !defined TZFILE_H */ diff --git a/unused/Makefile b/unused/Makefile new file mode 100644 index 000000000000..3865f23766ec --- /dev/null +++ b/unused/Makefile @@ -0,0 +1,418 @@ +# @(#)Makefile 8.7 + +# Change the line below for your time zone (after finding the zone you want in +# the time zone files, or adding it to a time zone file). +# Alternately, if you discover you've got the wrong time zone, you can just +# zic -l rightzone +# to correct things. +# Use the command +# make zonenames +# to get a list of the values you can use for LOCALTIME. + +LOCALTIME= Factory + +# If you want something other than Eastern United States time as a template +# for handling POSIX-style time zone environment variables, +# change the line below (after finding the zone you want in the +# time zone files, or adding it to a time zone file). +# (When a POSIX-style environment variable is handled, the rules in the +# template file are used to determine "spring forward" and "fall back" days and +# times; the environment variable itself specifies UTC offsets of standard and +# summer time.) +# Alternately, if you discover you've got the wrong time zone, you can just +# zic -p rightzone +# to correct things. +# Use the command +# make zonenames +# to get a list of the values you can use for POSIXRULES. +# If you want POSIX compatibility, use "America/New_York". + +POSIXRULES= America/New_York + +# Also see TZDEFRULESTRING below, which takes effect only +# if the time zone files cannot be accessed. + +# Everything gets put in subdirectories of. . . + +TOPDIR= /usr/local + +# "Compiled" time zone information is placed in the "TZDIR" directory +# (and subdirectories). +# Use an absolute path name for TZDIR unless you're just testing the software. + +TZDIR= $(TOPDIR)/etc/zoneinfo + +# The "tzselect", "zic", and "zdump" commands get installed in. . . + +ETCDIR= $(TOPDIR)/etc + +# If you "make INSTALL", the "date" command gets installed in. . . + +BINDIR= $(TOPDIR)/bin + +# Manual pages go in subdirectories of. . . + +MANDIR= $(TOPDIR)/man + +# Library functions are put in an archive in LIBDIR. + +LIBDIR= $(TOPDIR)/lib +TZLIB= $(LIBDIR)/libtz.a + +# If you always want time values interpreted as "seconds since the epoch +# (not counting leap seconds)", use +# REDO= posix_only +# below. If you always want right time values interpreted as "seconds since +# the epoch" (counting leap seconds)", use +# REDO= right_only +# below. If you want both sets of data available, with leap seconds not +# counted normally, use +# REDO= posix_right +# below. If you want both sets of data available, with leap seconds counted +# normally, use +# REDO= right_posix +# below. +# POSIX mandates that leap seconds not be counted; for compatibility with it, +# use either "posix_only" or "posix_right". + +REDO= posix_right + +# Since "." may not be in PATH... + +YEARISTYPE= ./yearistype + +# Non-default libraries needed to link. +# Add -lintl if you want to use `gettext' on Solaris. +LDLIBS= + +# Add the following to the end of the "CFLAGS=" line as needed. +# -DHAVE_ADJTIME=0 if `adjtime' does not exist (SVR0?) +# -DHAVE_GETTEXT=1 if `gettext' works (GNU, Linux, Solaris); also see LDLIBS +# -DHAVE_INCOMPATIBLE_CTIME_R=1 if your system's time.h declares +# ctime_r and asctime_r incompatibly with the POSIX standard (Solaris 8). +# -DHAVE_SETTIMEOFDAY=0 if settimeofday does not exist (SVR0?) +# -DHAVE_SETTIMEOFDAY=1 if settimeofday has just 1 arg (SVR4) +# -DHAVE_SETTIMEOFDAY=2 if settimeofday uses 2nd arg (4.3BSD) +# -DHAVE_SETTIMEOFDAY=3 if settimeofday ignores 2nd arg (4.4BSD) +# -DHAVE_STDINT_H=1 if you have a pre-C99 compiler with "stdint.h" +# -DHAVE_SYMLINK=0 if your system lacks the symlink function +# -DHAVE_SYS_STAT_H=0 if your compiler lacks a "sys/stat.h" +# -DHAVE_SYS_WAIT_H=0 if your compiler lacks a "sys/wait.h" +# -DLOCALE_HOME=\"path\" if locales are in "path", not "/usr/lib/locale" +# -DHAVE_UNISTD_H=0 if your compiler lacks a "unistd.h" (Microsoft C++ 7?) +# -DHAVE_UTMPX_H=1 if your compiler has a "utmpx.h" +# -DTZDEFRULESTRING=\",date/time,date/time\" to default to the specified +# DST transitions if the time zone files cannot be accessed +# -DTZ_DOMAIN=\"foo\" to use "foo" for gettext domain name; default is "tz" +# -TTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory; +# the default is system-supplied, typically "/usr/lib/locale" +# $(GCC_DEBUG_FLAGS) if you are using GCC and want lots of checking +# -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU=1 +# if you do not want run time warnings about formats that may cause +# year 2000 grief +# -DZIC_MAX_ABBR_LEN_WO_WARN=3 +# (or some other number) to set the maximum time zone abbreviation length +# that zic will accept without a warning (the default is 6) +GCC_DEBUG_FLAGS = -Dlint -g -O -fno-common \ + -Wall -Wcast-qual -Wconversion -Wmissing-prototypes \ + -Wnested-externs -Wpointer-arith -Wshadow \ + -Wtraditional # -Wstrict-prototypes -Wwrite-strings +# +# If you want to use System V compatibility code, add +# -DUSG_COMPAT +# to the end of the "CFLAGS=" line. This arrange for "timezone" and "daylight" +# variables to be kept up-to-date by the time conversion functions. Neither +# "timezone" nor "daylight" is described in X3J11's work. +# +# If your system has a "GMT offset" field in its "struct tm"s +# (or if you decide to add such a field in your system's "time.h" file), +# add the name to a define such as +# -DTM_GMTOFF=tm_gmtoff +# or +# -DTM_GMTOFF=_tm_gmtoff +# to the end of the "CFLAGS=" line. +# Neither tm_gmtoff nor _tm_gmtoff is described in X3J11's work; +# in its work, use of "tm_gmtoff" is described as non-conforming. +# Both Linux and BSD have done the equivalent of defining TM_GMTOFF in +# their recent releases. +# +# If your system has a "zone abbreviation" field in its "struct tm"s +# (or if you decide to add such a field in your system's "time.h" file), +# add the name to a define such as +# -DTM_ZONE=tm_zone +# or +# -DTM_ZONE=_tm_zone +# to the end of the "CFLAGS=" line. +# Neither tm_zone nor _tm_zone is described in X3J11's work; +# in its work, use of "tm_zone" is described as non-conforming. +# Both UCB and Sun have done the equivalent of defining TM_ZONE in +# their recent releases. +# +# If you want functions that were inspired by early versions of X3J11's work, +# add +# -DSTD_INSPIRED +# to the end of the "CFLAGS=" line. This arranges for the functions +# "tzsetwall", "offtime", "timelocal", "timegm", "timeoff", +# "posix2time", and "time2posix" to be added to the time conversion library. +# "tzsetwall" is like "tzset" except that it arranges for local wall clock +# time (rather than the time specified in the TZ environment variable) +# to be used. +# "offtime" is like "gmtime" except that it accepts a second (long) argument +# that gives an offset to add to the time_t when converting it. +# "timelocal" is equivalent to "mktime". +# "timegm" is like "timelocal" except that it turns a struct tm into +# a time_t using UTC (rather than local time as "timelocal" does). +# "timeoff" is like "timegm" except that it accepts a second (long) argument +# that gives an offset to use when converting to a time_t. +# "posix2time" and "time2posix" are described in an included manual page. +# X3J11's work does not describe any of these functions. +# Sun has provided "tzsetwall", "timelocal", and "timegm" in SunOS 4.0. +# These functions may well disappear in future releases of the time +# conversion package. +# +# If you want Source Code Control System ID's left out of object modules, add +# -DNOID +# to the end of the "CFLAGS=" line. +# +# If you'll never want to handle solar-time-based time zones, add +# -DNOSOLAR +# to the end of the "CFLAGS=" line +# (and comment out the "SDATA=" line below). +# This reduces (slightly) the run-time data-space requirements of +# the time conversion functions; it may reduce the acceptability of your system +# to folks in oil- and cash-rich places. +# +# If you want to allocate state structures in localtime, add +# -DALL_STATE +# to the end of the "CFLAGS=" line. Storage is obtained by calling malloc. +# +# If you want an "altzone" variable (a la System V Release 3.1), add +# -DALTZONE +# to the end of the "CFLAGS=" line. +# This variable is not described in X3J11's work. +# +# If you want a "gtime" function (a la MACH), add +# -DCMUCS +# to the end of the "CFLAGS=" line +# This function is not described in X3J11's work. +# +# NIST-PCTS:151-2, Version 1.4, (1993-12-03) is a test suite put +# out by the National Institute of Standards and Technology +# which claims to test C and Posix conformance. If you want to pass PCTS, add +# -DPCTS +# to the end of the "CFLAGS=" line. +# +# If you want strict compliance with XPG4 as of 1994-04-09, add +# -DXPG4_1994_04_09 +# to the end of the "CFLAGS=" line. This causes "strftime" to always return +# 53 as a week number (rather than 52 or 53) for those days in January that +# before the first Monday in January when a "%V" format is used and January 1 +# falls on a Friday, Saturday, or Sunday. + +CFLAGS= + +# If you want zic's -s option used when installing, uncomment the next line +# ZFLAGS= -s + +zic= ./zic +ZIC= $(zic) $(ZFLAGS) + +# The name of a Posix-compliant `awk' on your system. +AWK= nawk + +# The path where SGML DTDs are kept. +SGML_SEARCH_PATH= $(TOPDIR)/share/doc/sgml-lib/REC-html401-19991224/ + +# The catalog file(s) to use when validating. +SGML_CATALOG_FILES= HTML4.cat + +# The name, arguments and environment of a program to validate your web pages. +# See for a validator, and +# for a validation library. +VALIDATE = nsgmls +VALIDATE_FLAGS = -s -B -wall -wno-unused-param +VALIDATE_ENV = \ + SGML_CATALOG_FILES=$(SGML_CATALOG_FILES) \ + SGML_SEARCH_PATH=$(SGML_SEARCH_PATH) \ + SP_CHARSET_FIXED=YES \ + SP_ENCODING=UTF-8 + +############################################################################### + +cc= cc +CC= $(cc) -DTZDIR=\"$(TZDIR)\" + +TZCSRCS= zic.c localtime.c asctime.c scheck.c ialloc.c +TZCOBJS= zic.o localtime.o asctime.o scheck.o ialloc.o +TZDSRCS= zdump.c localtime.c ialloc.c +TZDOBJS= zdump.o localtime.o ialloc.o +DATESRCS= date.c localtime.c strftime.c asctime.c +DATEOBJS= date.o localtime.o strftime.o asctime.o +LIBSRCS= localtime.c asctime.c difftime.c +LIBOBJS= localtime.o asctime.o difftime.o +HEADERS= tzfile.h private.h +NONLIBSRCS= zic.c zdump.c scheck.c ialloc.c +NEWUCBSRCS= date.c strftime.c +SOURCES= $(HEADERS) $(LIBSRCS) $(NONLIBSRCS) $(NEWUCBSRCS) tzselect.ksh +MANS= newctime.3 newstrftime.3 newtzset.3 time2posix.3 \ + tzfile.5 tzselect.8 zic.8 zdump.8 +DOCS= README Theory $(MANS) date.1 Makefile +PRIMARY_YDATA= africa antarctica asia australasia \ + europe northamerica southamerica +YDATA= $(PRIMARY_YDATA) pacificnew etcetera factory backward +NDATA= systemv +SDATA= solar87 solar88 solar89 +TDATA= $(YDATA) $(NDATA) $(SDATA) +TABDATA= iso3166.tab zone.tab +DATA= $(YDATA) $(NDATA) $(SDATA) $(TABDATA) leapseconds yearistype.sh +WEB_PAGES= tz-art.htm tz-link.htm +MISC= usno1988 usno1989 usno1989a usno1995 usno1997 usno1998 \ + itca.jpg $(WEB_PAGES) checktab.awk workman.sh \ + zoneinfo2tdf.pl +ENCHILADA= $(DOCS) $(SOURCES) $(DATA) $(MISC) + +# And for the benefit of csh users on systems that assume the user +# shell should be used to handle commands in Makefiles. . . + +SHELL= /bin/sh + +all: tzselect zic zdump $(LIBOBJS) + +ALL: all date + +install: all $(DATA) $(REDO) $(TZLIB) $(MANS) $(TABDATA) + $(ZIC) -y $(YEARISTYPE) \ + -d $(TZDIR) -l $(LOCALTIME) -p $(POSIXRULES) + -rm -f $(TZDIR)/iso3166.tab $(TZDIR)/zone.tab + cp iso3166.tab zone.tab $(TZDIR)/. + -mkdir $(TOPDIR) $(ETCDIR) + cp tzselect zic zdump $(ETCDIR)/. + -mkdir $(TOPDIR) $(MANDIR) \ + $(MANDIR)/man3 $(MANDIR)/man5 $(MANDIR)/man8 + -rm -f $(MANDIR)/man3/newctime.3 \ + $(MANDIR)/man3/newtzset.3 \ + $(MANDIR)/man5/tzfile.5 \ + $(MANDIR)/man8/tzselect.8 \ + $(MANDIR)/man8/zdump.8 \ + $(MANDIR)/man8/zic.8 + cp newctime.3 newtzset.3 $(MANDIR)/man3/. + cp tzfile.5 $(MANDIR)/man5/. + cp tzselect.8 zdump.8 zic.8 $(MANDIR)/man8/. + +INSTALL: ALL install date.1 + -mkdir $(TOPDIR) $(BINDIR) + cp date $(BINDIR)/. + -mkdir $(TOPDIR) $(MANDIR) $(MANDIR)/man1 + -rm -f $(MANDIR)/man1/date.1 + cp date.1 $(MANDIR)/man1/. + +zdump: $(TZDOBJS) + $(CC) $(CFLAGS) $(LFLAGS) $(TZDOBJS) $(LDLIBS) -o $@ + +zic: $(TZCOBJS) yearistype + $(CC) $(CFLAGS) $(LFLAGS) $(TZCOBJS) $(LDLIBS) -o $@ + +yearistype: yearistype.sh + cp yearistype.sh yearistype + chmod +x yearistype + +posix_only: zic $(TDATA) + $(ZIC) -y $(YEARISTYPE) -d $(TZDIR) -L /dev/null $(TDATA) + +right_only: zic leapseconds $(TDATA) + $(ZIC) -y $(YEARISTYPE) -d $(TZDIR) -L leapseconds $(TDATA) + +# In earlier versions of this makefile, the other two directories were +# subdirectories of $(TZDIR). However, this led to configuration errors. +# For example, with posix_right under the earlier scheme, +# TZ='right/Australia/Adelaide' got you localtime with leap seconds, +# but gmtime without leap seconds, which led to problems with applications +# like sendmail that subtract gmtime from localtime. +# Therefore, the other two directories are now siblings of $(TZDIR). +# You must replace all of $(TZDIR) to switch from not using leap seconds +# to using them, or vice versa. +other_two: zic leapseconds $(TDATA) + $(ZIC) -y $(YEARISTYPE) -d $(TZDIR)-posix -L /dev/null $(TDATA) + $(ZIC) -y $(YEARISTYPE) \ + -d $(TZDIR)-leaps -L leapseconds $(TDATA) + +posix_right: posix_only other_two + +right_posix: right_only other_two + +zones: $(REDO) + +$(TZLIB): $(LIBOBJS) + -mkdir $(TOPDIR) $(LIBDIR) + ar ru $@ $(LIBOBJS) + if [ -x /usr/ucb/ranlib -o -x /usr/bin/ranlib ] ; \ + then ranlib $@ ; fi + +date: $(DATEOBJS) + $(CC) $(CFLAGS) date.o localtime.o asctime.o strftime.o \ + $(LDLIBS) -lc -o $@ + +tzselect: tzselect.ksh + sed \ + -e 's|AWK=[^}]*|AWK=$(AWK)|g' \ + -e 's|TZDIR=[^}]*|TZDIR=$(TZDIR)|' \ + <$? >$@ + chmod +x $@ + +check: check_tables check_web + +check_tables: checktab.awk $(PRIMARY_YDATA) + $(AWK) -f checktab.awk $(PRIMARY_YDATA) + +check_web: $(WEB_PAGES) + $(VALIDATE_ENV) $(VALIDATE) $(VALIDATE_FLAGS) $(WEB_PAGES) + +clean: + rm -f core *.o *.out tzselect zdump zic yearistype date + +maintainer-clean: clean + @echo 'This command is intended for maintainers to use; it' + @echo 'deletes files that may need special tools to rebuild.' + rm -f *.[1-8].txt tzcode.tar.gz tzdata.tar.gz + +names: + @echo $(ENCHILADA) + +# The zics below ensure that each data file can stand on its own. +# We also do an all-files run to catch links to links. + +public: $(ENCHILADA) + make maintainer-clean + make "CFLAGS=$(GCC_DEBUG_FLAGS)" + -mkdir /tmp/,tzpublic + -for i in $(TDATA) ; do zic -v -d /tmp/,tzpublic $$i 2>&1 | grep -v "starting year" ; done + for i in $(TDATA) ; do zic -d /tmp/,tzpublic $$i || exit; done + zic -v -d /tmp/,tzpublic $(TDATA) || exit + rm -f -r /tmp/,tzpublic + for i in *.[1-8] ; do sh workman.sh $$i > $$i.txt || exit; done + $(AWK) -f checktab.awk $(PRIMARY_YDATA) + tar cf - $(DOCS) $(SOURCES) $(MISC) *.[1-8].txt | gzip -9 > tzcode.tar.gz + tar cf - $(DATA) | gzip -9 > tzdata.tar.gz + +typecheck: + make clean + for i in "long long" unsigned double; \ + do \ + make CFLAGS="-DTYPECHECK -D_TIME_T \"-Dtime_t=$$i\"" ; \ + ./zdump -v Europe/Rome ; \ + make clean ; \ + done + +zonenames: $(TDATA) + @$(AWK) '/^Zone/ { print $$2 } /^Link/ { print $$3 }' $(TDATA) + +asctime.o: private.h tzfile.h +date.o: private.h +difftime.o: private.h +ialloc.o: private.h +localtime.o: private.h tzfile.h +scheck.o: private.h +strftime.o: tzfile.h +zic.o: private.h tzfile.h + +.KEEP_STATE: diff --git a/unused/checktab.awk b/unused/checktab.awk new file mode 100644 index 000000000000..80ad7d570158 --- /dev/null +++ b/unused/checktab.awk @@ -0,0 +1,159 @@ +# Check tz tables for consistency. + +# @(#)checktab.awk 8.1 + +# Contributed by Paul Eggert. + +BEGIN { + FS = "\t" + + if (!iso_table) iso_table = "iso3166.tab" + if (!zone_table) zone_table = "zone.tab" + if (!want_warnings) want_warnings = -1 + + while (getline >"/dev/stderr" + status = 1 + } + cc = $1 + name = $2 + if (cc !~ /^[A-Z][A-Z]$/) { + printf "%s:%d: invalid country code `%s'\n", \ + iso_table, iso_NR, cc >>"/dev/stderr" + status = 1 + } + if (cc <= cc0) { + if (cc == cc0) { + s = "duplicate"; + } else { + s = "out of order"; + } + + printf "%s:%d: country code `%s' is %s\n", \ + iso_table, iso_NR, cc, s \ + >>"/dev/stderr" + status = 1 + } + cc0 = cc + if (name2cc[name]) { + printf "%s:%d: `%s' and `%s' have the sname name\n", \ + iso_table, iso_NR, name2cc[name], cc \ + >>"/dev/stderr" + status = 1 + } + name2cc[name] = cc + cc2name[cc] = name + cc2NR[cc] = iso_NR + } + + zone_table = "zone.tab" + cc0 = "" + + while (getline >"/dev/stderr" + status = 1 + } + cc = $1 + coordinates = $2 + tz = $3 + comments = $4 + if (cc < cc0) { + printf "%s:%d: country code `%s' is out of order\n", \ + zone_table, zone_NR, cc >>"/dev/stderr" + status = 1 + } + cc0 = cc + if (tz2cc[tz]) { + printf "%s:%d: %s: duplicate TZ column\n", \ + zone_table, zone_NR, tz >>"/dev/stderr" + status = 1 + } + tz2cc[tz] = cc + tz2comments[tz] = comments + tz2NR[tz] = zone_NR + if (cc2name[cc]) { + cc_used[cc]++ + } else { + printf "%s:%d: %s: unknown country code\n", \ + zone_table, zone_NR, cc >>"/dev/stderr" + status = 1 + } + if (coordinates !~ /^[-+][0-9][0-9][0-5][0-9][-+][01][0-9][0-9][0-5][0-9]$/ \ + && coordinates !~ /^[-+][0-9][0-9][0-5][0-9][0-5][0-9][-+][01][0-9][0-9][0-5][0-9][0-5][0-9]$/) { + printf "%s:%d: %s: invalid coordinates\n", \ + zone_table, zone_NR, coordinates >>"/dev/stderr" + status = 1 + } + } + + for (tz in tz2cc) { + if (cc_used[tz2cc[tz]] == 1) { + if (tz2comments[tz]) { + printf "%s:%d: unnecessary comment `%s'\n", \ + zone_table, tz2NR[tz], tz2comments[tz] \ + >>"/dev/stderr" + status = 1 + } + } else { + if (!tz2comments[tz]) { + printf "%s:%d: missing comment\n", \ + zone_table, tz2NR[tz] >>"/dev/stderr" + status = 1 + } + } + } + + FS = " " +} + +{ + tz = "" + if ($1 == "Zone") tz = $2 + if ($1 == "Link") { + # Ignore Link commands if source and destination basenames + # are identical, e.g. Europe/Istanbul versus Asia/Istanbul. + src = $2 + dst = $3 + while ((i = index(src, "/"))) src = substr(src, i+1) + while ((i = index(dst, "/"))) dst = substr(dst, i+1) + if (src != dst) tz = $3 + } + if (tz && tz ~ /\//) { + if (!tz2cc[tz]) { + printf "%s: no data for `%s'\n", zone_table, tz \ + >>"/dev/stderr" + status = 1 + } + zoneSeen[tz] = 1 + } +} + +END { + for (tz in tz2cc) { + if (!zoneSeen[tz]) { + printf "%s:%d: no Zone table for `%s'\n", \ + zone_table, tz2NR[tz], tz >>"/dev/stderr" + status = 1 + } + } + + if (0 < want_warnings) { + for (cc in cc2name) { + if (!cc_used[cc]) { + printf "%s:%d: warning: " \ + "no Zone entries for %s (%s)\n", \ + iso_table, cc2NR[cc], cc, cc2name[cc] + } + } + } + + exit status +} diff --git a/unused/date.1 b/unused/date.1 new file mode 100644 index 000000000000..3c75ba4337c8 --- /dev/null +++ b/unused/date.1 @@ -0,0 +1,175 @@ +.TH DATE 1 +.SH NAME +date \- show and set date and time +.SH SYNOPSIS +.if n .nh +.if n .na +.B date +[ +.B \-u +] [ +.B \-c +] [ +.B \-n +] [ +.B \-d +dsttype +] [ +.B \-t +minutes-west +] [ +\fB\-a \fR[\fB+\fR|\fB-]\fIsss\fB.\fIfff\fR +] [ +.BI + format +] [ +\fR[\fIyyyy\fR]\fImmddhhmm\fR[\fIyy\fR][\fB.\fIss\fR] +] +.SH DESCRIPTION +.I Date +without arguments writes the date and time to the standard output in +the form +.ce 1 +Wed Mar 8 14:54:40 EST 1989 +.br +with +.B EST +replaced by the local time zone's abbreviation +(or by the abbreviation for the time zone specified in the +.B TZ +environment variable if set). +The exact output format depends on the locale. +.PP +If a command-line argument starts with a plus sign +.RB (` + '), +the rest of the argument is used as a +.I format +that controls what appears in the output. +In the format, when a percent sign +.RB (` % ') +appears, +it and the character after it are not output, +but rather identify part of the date or time +to be output in a particular way +(or identify a special character to output): +.nf +.sp +.if t .in +.5i +.if n .in +2 +.ta \w'%M\0\0'u +\w'Wed Mar 8 14:54:40 EST 1989\0\0'u + Sample output Explanation +%a Wed Abbreviated weekday name* +%A Wednesday Full weekday name* +%b Mar Abbreviated month name* +%B March Full month name* +%c Wed Mar 08 14:54:40 1989 Date and time* +%C 19 Century +%d 08 Day of month (always two digits) +%D 03/08/89 Month/day/year (eight characters) +%e 8 Day of month (leading zero blanked) +%h Mar Abbreviated month name* +%H 14 24-hour-clock hour (two digits) +%I 02 12-hour-clock hour (two digits) +%j 067 Julian day number (three digits) +%k 2 12-hour-clock hour (leading zero blanked) +%l 14 24-hour-clock hour (leading zero blanked) +%m 03 Month number (two digits) +%M 54 Minute (two digits) +%n \\n newline character +%p PM AM/PM designation +%r 02:54:40 PM Hour:minute:second AM/PM designation +%R 14:54 Hour:minute +%S 40 Second (two digits) +%t \\t tab character +%T 14:54:40 Hour:minute:second +%U 10 Sunday-based week number (two digits) +%w 3 Day number (one digit, Sunday is 0) +%W 10 Monday-based week number (two digits) +%x 03/08/89 Date* +%X 14:54:40 Time* +%y 89 Last two digits of year +%Y 1989 Year in full +%Z EST Time zone abbreviation +%+ Wed Mar 8 14:54:40 EST 1989 Default output format* +.if t .in -.5i +.if n .in -2 +* The exact output depends on the locale. +.sp +.fi +If a character other than one of those shown above appears after +a percent sign in the format, +that following character is output. +All other characters in the format are copied unchanged to the output; +a newline character is always added at the end of the output. +.PP +In Sunday-based week numbering, +the first Sunday of the year begins week 1; +days preceding it are part of ``week 0.'' +In Monday-based week numbering, +the first Monday of the year begins week 1. +.PP +To set the date, use a command line argument with one of the following forms: +.nf +.if t .in +.5i +.if n .in +2 +.ta \w'198903081454\0'u +1454 24-hour-clock hours (first two digits) and minutes +081454 Month day (first two digits), hours, and minutes +03081454 Month (two digits, January is 01), month day, hours, minutes +8903081454 Year, month, month day, hours, minutes +0308145489 Month, month day, hours, minutes, year + (on System V-compatible systems) +030814541989 Month, month day, hours, minutes, four-digit year +198903081454 Four-digit year, month, month day, hours, minutes +.if t .in -.5i +.if n .in -2 +.fi +If the century, year, month, or month day is not given, +the current value is used. +Any of the above forms may be followed by a period and two digits that give +the seconds part of the new time; if no seconds are given, zero is assumed. +.PP +These options are available: +.TP +.BR \-u " or " \-c +Use UTC when setting and showing the date and time. +.TP +.B \-n +Do not notify other networked systems of the time change. +.TP +.BI "\-d " dsttype +Set the kernel-stored Daylight Saving Time type to the given value. +(The kernel-stored DST type is used mostly by ``old'' binaries.) +.TP +.BI "\-t " minutes-west +Set the kernel-stored ``minutes west of UTC'' value to the one given on the +command line. +(The kernel-stored DST type is used mostly by ``old'' binaries.) +.TP +.BI "\-a " adjustment +Change the time forward (or backward) by the number of seconds +(and fractions thereof) specified in the +.I adjustment\^ +argument. +Either the seconds part or the fractions part of the argument (but not both) +may be omitted. +On BSD-based systems, +the adjustment is made by changing the rate at which time advances; +on System-V-based systems, the adjustment is made by changing the time. +.SH FILES +.ta \w'/usr/local/etc/zoneinfo/posixrules\0\0'u +/usr/lib/locale/\f2L\fP/LC_TIME description of time locale \f2L\fP +.br +/usr/local/etc/zoneinfo time zone information directory +.br +/usr/local/etc/zoneinfo/localtime local time zone file +.br +/usr/local/etc/zoneinfo/posixrules used with POSIX-style TZ's +.br +/usr/local/etc/zoneinfo/GMT for UTC leap seconds +.sp +If +.B /usr/local/etc/zoneinfo/GMT +is absent, +UTC leap seconds are loaded from +.BR /usr/local/etc/zoneinfo/posixrules . +.\" @(#)date.1 8.1 diff --git a/unused/date.1.txt b/unused/date.1.txt new file mode 100644 index 000000000000..2910aaac370c --- /dev/null +++ b/unused/date.1.txt @@ -0,0 +1,127 @@ +NAME + + date - show and set date and time + +SYNOPSIS + date [ -u ] [ -c ] [ -n ] [ -d dsttype ] [ -t minutes-west ] + [ -a [+|-]sss.fff ] [ +format ] [ [yyyy]mmddhhmm[yy][.ss] ] + +DESCRIPTION + Date without arguments writes the date and time to the + standard output in the form + Wed Mar 8 14:54:40 EST 1989 + with EST replaced by the local time zone's abbreviation (or + by the abbreviation for the time zone specified in the TZ + environment variable if set). The exact output format + depends on the locale. + + If a command-line argument starts with a plus sign (`+'), + the rest of the argument is used as a format that controls + what appears in the output. In the format, when a percent + sign (`%') appears, it and the character after it are not + output, but rather identify part of the date or time to be + output in a particular way (or identify a special character + to output): + + Sample output Explanation + %a Wed Abbreviated weekday name* + %A Wednesday Full weekday name* + %b Mar Abbreviated month name* + %B March Full month name* + %c Wed Mar 08 14:54:40 1989 Date and time* + %C 19 Century + %d 08 Day of month (always two digits) + %D 03/08/89 Month/day/year (eight characters) + %e 8 Day of month (leading zero blanked) + %h Mar Abbreviated month name* + %H 14 24-hour-clock hour (two digits) + %I 02 12-hour-clock hour (two digits) + %j 067 Julian day number (three digits) + %k 2 12-hour-clock hour (leading zero blanked) + %l 14 24-hour-clock hour (leading zero blanked) + %m 03 Month number (two digits) + %M 54 Minute (two digits) + %n \n newline character + %p PM AM/PM designation + %r 02:54:40 PM Hour:minute:second AM/PM designation + %R 14:54 Hour:minute + %S 40 Second (two digits) + %t \t tab character + %T 14:54:40 Hour:minute:second + %U 10 Sunday-based week number (two digits) + %w 3 Day number (one digit, Sunday is 0) + %W 10 Monday-based week number (two digits) + %x 03/08/89 Date* + %X 14:54:40 Time* + %y 89 Last two digits of year + %Y 1989 Year in full + %Z EST Time zone abbreviation + %+ Wed Mar 8 14:54:40 EST 1989 Default output format* + * The exact output depends on the locale. + + If a character other than one of those shown above appears + after a percent sign in the format, that following character + is output. All other characters in the format are copied + unchanged to the output; a newline character is always added + at the end of the output. + In Sunday-based week numbering, the first Sunday of the year + begins week 1; days preceding it are part of ``week 0.'' In + Monday-based week numbering, the first Monday of the year + begins week 1. + + To set the date, use a command line argument with one of the + following forms: + 1454 24-hour-clock hours (first two digits) and minutes + 081454 Month day (first two digits), hours, and minutes + 03081454 Month (two digits, January is 01), month day, hours, minutes + 8903081454 Year, month, month day, hours, minutes + 0308145489 Month, month day, hours, minutes, year + (on System V-compatible systems) + 030814541989 Month, month day, hours, minutes, four-digit year + 198903081454 Four-digit year, month, month day, hours, minutes + If the century, year, month, or month day is not given, the + current value is used. Any of the above forms may be + followed by a period and two digits that give the seconds + part of the new time; if no seconds are given, zero is + assumed. + + These options are available: + + -u or -c + Use UTC when setting and showing the date and time. + + -n Do not notify other networked systems of the time + change. + + -d dsttype + Set the kernel-stored Daylight Saving Time type to the + given value. (The kernel-stored DST type is used + mostly by ``old'' binaries.) + + -t minutes-west + Set the kernel-stored ``minutes west of UTC'' value to + the one given on the command line. (The kernel-stored + DST type is used mostly by ``old'' binaries.) + + -a adjustment + Change the time forward (or backward) by the number of + seconds (and fractions thereof) specified in the + adjustment argument. Either the seconds part or the + fractions part of the argument (but not both) may be + omitted. On BSD-based systems, the adjustment is made + by changing the rate at which time advances; on System- + V-based systems, the adjustment is made by changing the + time. + +FILES + /usr/lib/locale/L/LC_TIME description of time + locale L + /usr/local/etc/zoneinfo time zone information + directory + /usr/local/etc/zoneinfo/localtime local time zone file + /usr/local/etc/zoneinfo/posixrules used with POSIX-style + TZ's + /usr/local/etc/zoneinfo/GMT for UTC leap seconds + + If /usr/local/etc/zoneinfo/GMT is absent, UTC leap seconds + are loaded from /usr/local/etc/zoneinfo/posixrules. diff --git a/unused/date.c b/unused/date.c new file mode 100644 index 000000000000..6a6d2cdaffcd --- /dev/null +++ b/unused/date.c @@ -0,0 +1,945 @@ +#ifndef lint +#ifndef NOID +static char elsieid[] = "@(#)date.c 8.4"; +/* +** Modified from the UCB version with the SCCS ID appearing below. +*/ +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* + * Copyright (c) 1985, 1987, 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANT[A]BILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +char copyright[] = +"@(#) Copyright (c) 1985, 1987, 1988 The Regents of the University of California.\n\ + All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)date.c 4.23 (Berkeley) 9/20/88"; +#endif /* not lint */ + +#include "private.h" +#if HAVE_ADJTIME || HAVE_SETTIMEOFDAY +#include "sys/time.h" /* for struct timeval, struct timezone */ +#endif /* HAVE_ADJTIME || HAVE_SETTIMEOFDAY */ +#include "locale.h" +#include "utmp.h" /* for OLD_TIME (or its absence) */ +#if HAVE_UTMPX_H +#include "utmpx.h" +#endif + +#ifndef OTIME_MSG +#define OTIME_MSG "old time" +#endif +#ifndef NTIME_MSG +#define NTIME_MSG "new time" +#endif + +/* +** The two things date knows about time are. . . +*/ + +#ifndef TM_YEAR_BASE +#define TM_YEAR_BASE 1900 +#endif /* !defined TM_YEAR_BASE */ + +#ifndef SECSPERMIN +#define SECSPERMIN 60 +#endif /* !defined SECSPERMIN */ + +extern double atof(); +extern char ** environ; +extern char * getlogin(); +extern time_t mktime(); +extern char * optarg; +extern int optind; +extern char * strchr(); +extern time_t time(); +extern char * tzname[2]; + +static int retval = EXIT_SUCCESS; + +static void checkfinal(const char *, int, time_t, time_t); +static int comptm(const struct tm *, const struct tm *); +static time_t convert(const char *, int, time_t); +static void display(const char *); +static void dogmt(void); +static void errensure(void); +static void iffy(time_t, time_t, const char *, const char *); +int main(int, char**); +static const char * nondigit(const char *); +static void oops(const char *); +static void reset(time_t, int); +static void timeout(FILE *, const char *, const struct tm *); +static void usage(void); +static void wildinput(const char *, const char *, + const char *); + +int +main(argc, argv) +const int argc; +char * argv[]; +{ + register const char * format; + register const char * value; + register const char * cp; + register int ch; + register int dousg; + register int aflag = 0; + register int dflag = 0; + register int nflag = 0; + register int tflag = 0; + register int minuteswest; + register int dsttime; + register double adjust; + time_t now; + time_t t; + + INITIALIZE(dousg); + INITIALIZE(minuteswest); + INITIALIZE(dsttime); + INITIALIZE(adjust); + INITIALIZE(t); +#ifdef LC_ALL + (void) setlocale(LC_ALL, ""); +#endif /* defined(LC_ALL) */ +#if HAVE_GETTEXT +#ifdef TZ_DOMAINDIR + (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); +#endif /* defined(TEXTDOMAINDIR) */ + (void) textdomain(TZ_DOMAIN); +#endif /* HAVE_GETTEXT */ + (void) time(&now); + format = value = NULL; + while ((ch = getopt(argc, argv, "ucnd:t:a:")) != EOF && ch != -1) { + switch (ch) { + default: + usage(); + case 'u': /* do it in UTC */ + case 'c': + dogmt(); + break; + case 'n': /* don't set network */ + nflag = 1; + break; + case 'd': /* daylight saving time */ + if (dflag) { + (void) fprintf(stderr, + _("date: error: multiple -d's used")); + usage(); + } + dflag = 1; + cp = optarg; + dsttime = atoi(cp); + if (*cp == '\0' || *nondigit(cp) != '\0') + wildinput(_("-t value"), optarg, + _("must be a non-negative number")); + break; + case 't': /* minutes west of UTC */ + if (tflag) { + (void) fprintf(stderr, + _("date: error: multiple -t's used")); + usage(); + } + tflag = 1; + cp = optarg; + minuteswest = atoi(cp); + if (*cp == '+' || *cp == '-') + ++cp; + if (*cp == '\0' || *nondigit(cp) != '\0') + wildinput(_("-d value"), optarg, + _("must be a number")); + break; + case 'a': /* adjustment */ + if (aflag) { + (void) fprintf(stderr, + _("date: error: multiple -a's used")); + usage(); + } + aflag = 1; + cp = optarg; + adjust = atof(cp); + if (*cp == '+' || *cp == '-') + ++cp; + if (*cp == '\0' || strcmp(cp, ".") == 0) + wildinput(_("-a value"), optarg, + _("must be a number")); + cp = nondigit(cp); + if (*cp == '.') + ++cp; + if (*nondigit(cp) != '\0') + wildinput(_("-a value"), optarg, + _("must be a number")); + break; + } + } + while (optind < argc) { + cp = argv[optind++]; + if (*cp == '+') + if (format == NULL) + format = cp + 1; + else { + (void) fprintf(stderr, +_("date: error: multiple formats in command line\n")); + usage(); + } + else if (value == NULL) + value = cp; + else { + (void) fprintf(stderr, +_("date: error: multiple values in command line\n")); + usage(); + } + } + if (value != NULL) { + /* + ** This order ensures that "reasonable" twelve-digit inputs + ** (such as 120203042006) won't be misinterpreted + ** even if time_t's range all the way back to the thirteenth + ** century. Do not change the order. + */ + t = convert(value, (dousg = TRUE), now); + if (t == -1) + t = convert(value, (dousg = FALSE), now); + if (t == -1) { + /* + ** Out of range values, + ** or time that falls in a DST transition hole? + */ + if ((cp = strchr(value, '.')) != NULL) { + /* + ** Ensure that the failure of + ** TZ=America/New_York date 8712312359.60 + ** doesn't get misdiagnosed. (It was + ** TZ=America/New_York date 8712311859.60 + ** when the leap second was inserted.) + ** The normal check won't work since + ** the given time is valid in UTC. + */ + if (atoi(cp + 1) >= SECSPERMIN) + wildinput(_("time"), value, + _("out of range seconds given")); + } + dogmt(); + t = convert(value, FALSE, now); + if (t == -1) + t = convert(value, TRUE, now); + wildinput(_("time"), value, + (t == -1) ? + _("out of range value given") : + _("time skipped when clock springs forward")); + } + } + /* + ** Entire command line has now been checked. + */ + if (aflag) { +#if HAVE_ADJTIME + struct timeval tv; + + tv.tv_sec = (int) adjust; + tv.tv_usec = (int) ((adjust - tv.tv_sec) * 1000000L); + if (adjtime(&tv, (struct timeval *) NULL) != 0) + oops("adjtime"); +#endif /* HAVE_ADJTIME */ +#if !HAVE_ADJTIME + reset((time_t) (now + adjust), nflag); +#endif /* !HAVE_ADJTIME */ + /* + ** Sun silently ignores everything else; we follow suit. + */ + exit(retval); + } + if (dflag || tflag) { +#if HAVE_SETTIMEOFDAY == 2 + struct timezone tz; + + if (!dflag || !tflag) + if (gettimeofday((struct timeval *) NULL, &tz) != 0) + oops("gettimeofday"); + if (dflag) + tz.tz_dsttime = dsttime; + if (tflag) + tz.tz_minuteswest = minuteswest; + if (settimeofday((struct timeval *) NULL, &tz) != 0) + oops("settimeofday"); +#endif /* HAVE_SETTIMEOFDAY == 2 */ +#if HAVE_SETTIMEOFDAY != 2 + (void) fprintf(stderr, +_("date: warning: kernel doesn't keep -d/-t information, option ignored\n")); +#endif /* HAVE_SETTIMEOFDAY != 2 */ + } + + if (value == NULL) + display(format); + + reset(t, nflag); + + checkfinal(value, dousg, t, now); + +#ifdef EBUG + { + struct tm tm; + + tm = *localtime(&t); + timeout(stdout, "%c\n", &tm); + exit(retval); + } +#endif /* defined EBUG */ + + display(format); + + /* gcc -Wall pacifier */ + for ( ; ; ) + continue; +} + +static void +dogmt(void) +{ + static char ** fakeenv; + + if (fakeenv == NULL) { + register int from; + register int to; + register int n; + static char tzegmt0[] = "TZ=GMT0"; + + for (n = 0; environ[n] != NULL; ++n) + continue; + fakeenv = (char **) malloc((size_t) (n + 2) * sizeof *fakeenv); + if (fakeenv == NULL) { + (void) perror(_("Memory exhausted")); + errensure(); + exit(retval); + } + to = 0; + fakeenv[to++] = tzegmt0; + for (from = 1; environ[from] != NULL; ++from) + if (strncmp(environ[from], "TZ=", 3) != 0) + fakeenv[to++] = environ[from]; + fakeenv[to] = NULL; + environ = fakeenv; + } +} + +#ifdef OLD_TIME + +/* +** We assume we're on a System-V-based system, +** should use stime, +** should write System-V-format utmp entries, +** and don't have network notification to worry about. +*/ + +#include "fcntl.h" /* for O_WRONLY, O_APPEND */ + +/*ARGSUSED*/ +static void +reset(const time_t newt, const int nflag) +{ + register int fid; + time_t oldt; + static struct { + struct utmp before; + struct utmp after; + } s; +#if HAVE_UTMPX_H + static struct { + struct utmpx before; + struct utmpx after; + } sx; +#endif + + /* + ** Wouldn't it be great if stime returned the old time? + */ + (void) time(&oldt); + if (stime(&newt) != 0) + oops("stime"); + s.before.ut_type = OLD_TIME; + s.before.ut_time = oldt; + (void) strcpy(s.before.ut_line, OTIME_MSG); + s.after.ut_type = NEW_TIME; + s.after.ut_time = newt; + (void) strcpy(s.after.ut_line, NTIME_MSG); + fid = open(WTMP_FILE, O_WRONLY | O_APPEND); + if (fid < 0) + oops(_("log file open")); + if (write(fid, (char *) &s, sizeof s) != sizeof s) + oops(_("log file write")); + if (close(fid) != 0) + oops(_("log file close")); +#if !HAVE_UTMPX_H + pututline(&s.before); + pututline(&s.after); +#endif /* !HAVE_UTMPX_H */ +#if HAVE_UTMPX_H + sx.before.ut_type = OLD_TIME; + sx.before.ut_tv.tv_sec = oldt; + (void) strcpy(sx.before.ut_line, OTIME_MSG); + sx.after.ut_type = NEW_TIME; + sx.after.ut_tv.tv_sec = newt; + (void) strcpy(sx.after.ut_line, NTIME_MSG); +#if !SUPPRESS_WTMPX_FILE_UPDATE + /* In Solaris 2.5 (and presumably other systems), + `date' does not update /var/adm/wtmpx. + This must be a bug. If you'd like to reproduce the bug, + define SUPPRESS_WTMPX_FILE_UPDATE to be nonzero. */ + fid = open(WTMPX_FILE, O_WRONLY | O_APPEND); + if (fid < 0) + oops(_("log file open")); + if (write(fid, (char *) &sx, sizeof sx) != sizeof sx) + oops(_("log file write")); + if (close(fid) != 0) + oops(_("log file close")); +#endif /* !SUPPRESS_WTMPX_FILE_UPDATE */ + pututxline(&sx.before); + pututxline(&sx.after); +#endif /* HAVE_UTMPX_H */ +} + +#endif /* defined OLD_TIME */ +#ifndef OLD_TIME + +/* +** We assume we're on a BSD-based system, +** should use settimeofday, +** should write BSD-format utmp entries (using logwtmp), +** and may get to worry about network notification. +** The "time name" changes between 4.3-tahoe and 4.4; +** we include sys/param.h to determine which we should use. +*/ + +#ifndef TIME_NAME +#include "sys/param.h" +#ifdef BSD4_4 +#define TIME_NAME "date" +#endif /* defined BSD4_4 */ +#ifndef BSD4_4 +#define TIME_NAME "" +#endif /* !defined BSD4_4 */ +#endif /* !defined TIME_NAME */ + +#include "syslog.h" +#include "sys/socket.h" +#include "netinet/in.h" +#include "netdb.h" +#define TSPTYPES +#include "protocols/timed.h" + +extern int logwtmp(); + +#if HAVE_SETTIMEOFDAY == 1 +#define settimeofday(t, tz) (settimeofday)(t) +#endif /* HAVE_SETTIMEOFDAY == 1 */ + +#ifndef TSP_SETDATE +/*ARGSUSED*/ +#endif /* !defined TSP_SETDATE */ +static void +reset(newt, nflag) +const time_t newt; +const int nflag; +{ + register const char * username; + static struct timeval tv; /* static so tv_usec is 0 */ + +#ifdef EBUG + return; +#endif /* defined EBUG */ + username = getlogin(); + if (username == NULL || *username == '\0') /* single-user or no tty */ + username = "root"; + tv.tv_sec = newt; +#ifdef TSP_SETDATE + if (nflag || !netsettime(tv)) +#endif /* defined TSP_SETDATE */ + { + /* + ** "old" entry is always written, for compatibility. + */ + logwtmp("|", TIME_NAME, ""); + if (settimeofday(&tv, (struct timezone *) NULL) == 0) { + logwtmp("{", TIME_NAME, ""); /* } */ + syslog(LOG_AUTH | LOG_NOTICE, _("date set by %s"), + username); + } else oops("settimeofday"); + } +} + +#endif /* !defined OLD_TIME */ + +static void +wildinput(item, value, reason) +const char * const item; +const char * const value; +const char * const reason; +{ + (void) fprintf(stderr, + _("date: error: bad command line %s \"%s\", %s\n"), + item, value, reason); + usage(); +} + +static void +errensure(void) +{ + if (retval == EXIT_SUCCESS) + retval = EXIT_FAILURE; +} + +static const char * +nondigit(cp) +register const char * cp; +{ + while (is_digit(*cp)) + ++cp; + return cp; +} + +static void +usage(void) +{ + (void) fprintf(stderr, _("date: usage is date [-u] [-c] [-n] [-d dst] \ +[-t min-west] [-a sss.fff] [[yyyy]mmddhhmm[yyyy][.ss]] [+format]\n")); + errensure(); + exit(retval); +} + +static void +oops(string) +const char * const string; +{ + int e = errno; + + (void) fprintf(stderr, _("date: error: ")); + errno = e; + (void) perror(string); + errensure(); + display((char *) NULL); +} + +static void +display(format) +const char * const format; +{ + struct tm tm; + time_t now; + + (void) time(&now); + tm = *localtime(&now); + timeout(stdout, format ? format : "%+", &tm); + (void) putchar('\n'); + (void) fflush(stdout); + (void) fflush(stderr); + if (ferror(stdout) || ferror(stderr)) { + (void) fprintf(stderr, + _("date: error: couldn't write results\n")); + errensure(); + } + exit(retval); +} + +extern size_t strftime(); + +#define INCR 1024 + +static void +timeout(fp, format, tmp) +FILE * const fp; +const char * const format; +const struct tm * const tmp; +{ + char * cp; + size_t result; + size_t size; + + if (*format == '\0') + return; + size = INCR; + cp = malloc((size_t) size); + for ( ; ; ) { + if (cp == NULL) { + (void) fprintf(stderr, + _("date: error: can't get memory\n")); + errensure(); + exit(retval); + } + cp[0] = '\1'; + result = strftime(cp, size, format, tmp); + if (result != 0 || cp[0] == '\0') + break; + size += INCR; + cp = realloc(cp, (size_t) size); + } + (void) fwrite(cp, 1, result, fp); + free(cp); +} + +static int +comptm(atmp, btmp) +register const struct tm * const atmp; +register const struct tm * const btmp; +{ + register int result; + + if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && + (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && + (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && + (result = (atmp->tm_min - btmp->tm_min)) == 0) + result = atmp->tm_sec - btmp->tm_sec; + return result; +} + +/* +** convert -- +** convert user's input into a time_t. +*/ + +#define ATOI2(ar) (ar[0] - '0') * 10 + (ar[1] - '0'); ar += 2; + +static time_t +convert(register const char * const value, const int dousg, const time_t t) +{ + register const char * cp; + register const char * dotp; + register int cent, year_in_cent, month, hour, day, mins, secs; + struct tm tm, outtm; + time_t outt; + + tm = *localtime(&t); +#define DIVISOR 100 + year_in_cent = tm.tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR; + cent = tm.tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR + + year_in_cent / DIVISOR; + year_in_cent %= DIVISOR; + if (year_in_cent < 0) { + year_in_cent += DIVISOR; + --cent; + } + month = tm.tm_mon + 1; + day = tm.tm_mday; + hour = tm.tm_hour; + mins = tm.tm_min; + secs = 0; + + dotp = strchr(value, '.'); + for (cp = value; *cp != '\0'; ++cp) + if (!is_digit(*cp) && cp != dotp) + wildinput(_("time"), value, _("contains a nondigit")); + + if (dotp == NULL) + dotp = strchr(value, '\0'); + else { + cp = dotp + 1; + if (strlen(cp) != 2) + wildinput(_("time"), value, + _("seconds part is not two digits")); + secs = ATOI2(cp); + } + + cp = value; + switch (dotp - cp) { + default: + wildinput(_("time"), value, + _("main part is wrong length")); + case 12: + if (!dousg) { + cent = ATOI2(cp); + year_in_cent = ATOI2(cp); + } + month = ATOI2(cp); + day = ATOI2(cp); + hour = ATOI2(cp); + mins = ATOI2(cp); + if (dousg) { + cent = ATOI2(cp); + year_in_cent = ATOI2(cp); + } + break; + case 8: /* mmddhhmm */ + month = ATOI2(cp); + /* fall through to. . . */ + case 6: /* ddhhmm */ + day = ATOI2(cp); + /* fall through to. . . */ + case 4: /* hhmm */ + hour = ATOI2(cp); + mins = ATOI2(cp); + break; + case 10: + if (!dousg) { + year_in_cent = ATOI2(cp); + } + month = ATOI2(cp); + day = ATOI2(cp); + hour = ATOI2(cp); + mins = ATOI2(cp); + if (dousg) { + year_in_cent = ATOI2(cp); + } + break; + } + + tm.tm_year = cent * 100 + year_in_cent - TM_YEAR_BASE; + tm.tm_mon = month - 1; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = mins; + tm.tm_sec = secs; + tm.tm_isdst = -1; + outtm = tm; + outt = mktime(&outtm); + return (comptm(&tm, &outtm) == 0) ? outt : -1; +} + +/* +** Code from here on out is either based on code provided by UCB +** or is only called just before the program exits. +*/ + +/* +** Check for iffy input. +*/ + +static void +checkfinal(const char * const value, + const int didusg, + const time_t t, + const time_t oldnow) +{ + time_t othert; + struct tm tm; + struct tm othertm; + register int pass; + register long offset; + + /* + ** See if there's both a USG and a BSD interpretation. + */ + othert = convert(value, !didusg, oldnow); + if (othert != -1 && othert != t) + iffy(t, othert, value, _("year could be at start or end")); + /* + ** See if there's both a DST and a STD version. + */ + tm = *localtime(&t); + othertm = tm; + othertm.tm_isdst = !tm.tm_isdst; + othert = mktime(&othertm); + if (othert != -1 && othertm.tm_isdst != tm.tm_isdst && + comptm(&tm, &othertm) == 0) + iffy(t, othert, value, + _("both standard and summer time versions exist")); +/* +** Final check. +** +** If a jurisdiction shifts time *without* shifting whether time is +** summer or standard (as Hawaii, the United Kingdom, and Saudi Arabia +** have done), routine checks for iffy times may not work. +** So we perform this final check, deferring it until after the time has +** been set--it may take a while, and we don't want to introduce an unnecessary +** lag between the time the user enters their command and the time that +** stime/settimeofday is called. +** +** We just check nearby times to see if any have the same representation +** as the time that convert returned. We work our way out from the center +** for quick response in solar time situations. We only handle common cases-- +** offsets of at most a minute, and offsets of exact numbers of minutes +** and at most an hour. +*/ + for (offset = 1; offset <= 60; ++offset) + for (pass = 1; pass <= 4; ++pass) { + if (pass == 1) + othert = t + offset; + else if (pass == 2) + othert = t - offset; + else if (pass == 3) + othert = t + 60 * offset; + else othert = t - 60 * offset; + othertm = *localtime(&othert); + if (comptm(&tm, &othertm) == 0) + iffy(t, othert, value, + _("multiple matching times exist")); + } +} + +static void +iffy(const time_t thist, const time_t thatt, + const char * const value, const char * const reason) +{ + struct tm tm; + + (void) fprintf(stderr, _("date: warning: ambiguous time \"%s\", %s.\n"), + value, reason); + tm = *gmtime(&thist); + /* + ** Avoid running afoul of SCCS! + */ + timeout(stderr, _("Time was set as if you used\n\tdate -u %m%d%H\ +%M\ +%Y.%S\n"), &tm); + tm = *localtime(&thist); + timeout(stderr, _("to get %c"), &tm); + (void) fprintf(stderr, _(" (%s). Use\n"), + tm.tm_isdst ? _("summer time") : _("standard time")); + tm = *gmtime(&thatt); + timeout(stderr, _("\tdate -u %m%d%H\ +%M\ +%Y.%S\n"), &tm); + tm = *localtime(&thatt); + timeout(stderr, _("to get %c"), &tm); + (void) fprintf(stderr, _(" (%s).\n"), + tm.tm_isdst ? _("summer time") : _("standard time")); + errensure(); + exit(retval); +} + +#ifdef TSP_SETDATE +#define WAITACK 2 /* seconds */ +#define WAITDATEACK 5 /* seconds */ + +/* + * Set the date in the machines controlled by timedaemons + * by communicating the new date to the local timedaemon. + * If the timedaemon is in the master state, it performs the + * correction on all slaves. If it is in the slave state, it + * notifies the master that a correction is needed. + * Returns 1 on success, 0 on failure. + */ +netsettime(ntv) + struct timeval ntv; +{ + int s, length, port, timed_ack, found, err; + long waittime; + fd_set ready; + char hostname[MAXHOSTNAMELEN]; + struct timeval tout; + struct servent *sp; + struct tsp msg; + struct sockaddr_in sin, dest, from; + + sp = getservbyname("timed", "udp"); + if (sp == 0) { + fputs(_("udp/timed: unknown service\n"), stderr); + retval = 2; + return (0); + } + dest.sin_port = sp->s_port; + dest.sin_family = AF_INET; + dest.sin_addr.s_addr = htonl((u_long)INADDR_ANY); + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + if (errno != EPROTONOSUPPORT) + perror("date: socket"); + goto bad; + } + bzero((char *)&sin, sizeof (sin)); + sin.sin_family = AF_INET; + for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) { + sin.sin_port = htons((u_short)port); + if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0) + break; + if (errno != EADDRINUSE) { + if (errno != EADDRNOTAVAIL) + perror("date: bind"); + goto bad; + } + } + if (port == IPPORT_RESERVED / 2) { + fputs(_("date: All ports in use\n"), stderr); + goto bad; + } + msg.tsp_type = TSP_SETDATE; + msg.tsp_vers = TSPVERSION; + if (gethostname(hostname, sizeof (hostname))) { + perror("gethostname"); + goto bad; + } + (void) strncpy(msg.tsp_name, hostname, sizeof (hostname)); + msg.tsp_seq = htons((u_short)0); + msg.tsp_time.tv_sec = htonl((u_long)ntv.tv_sec); + msg.tsp_time.tv_usec = htonl((u_long)ntv.tv_usec); + length = sizeof (struct sockaddr_in); + if (connect(s, &dest, length) < 0) { + perror("date: connect"); + goto bad; + } + if (send(s, (char *)&msg, sizeof (struct tsp), 0) < 0) { + if (errno != ECONNREFUSED) + perror("date: send"); + goto bad; + } + timed_ack = -1; + waittime = WAITACK; +loop: + tout.tv_sec = waittime; + tout.tv_usec = 0; + FD_ZERO(&ready); + FD_SET(s, &ready); + found = select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout); + length = sizeof err; + if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char *)&err, &length) == 0 + && err) { + errno = err; + if (errno != ECONNREFUSED) + perror(_("date: send (delayed error)")); + goto bad; + } + if (found > 0 && FD_ISSET(s, &ready)) { + length = sizeof (struct sockaddr_in); + if (recvfrom(s, (char *)&msg, sizeof (struct tsp), 0, &from, + &length) < 0) { + if (errno != ECONNREFUSED) + perror("date: recvfrom"); + goto bad; + } + msg.tsp_seq = ntohs(msg.tsp_seq); + msg.tsp_time.tv_sec = ntohl(msg.tsp_time.tv_sec); + msg.tsp_time.tv_usec = ntohl(msg.tsp_time.tv_usec); + switch (msg.tsp_type) { + + case TSP_ACK: + timed_ack = TSP_ACK; + waittime = WAITDATEACK; + goto loop; + + case TSP_DATEACK: + (void)close(s); + return (1); + + default: + fprintf(stderr, + _("date: Wrong ack received from timed: %s\n"), + tsptype[msg.tsp_type]); + timed_ack = -1; + break; + } + } + if (timed_ack == -1) + fputs(_("date: Can't reach time daemon, time set locally.\n"), + stderr); +bad: + (void)close(s); + retval = 2; + return (0); +} +#endif /* defined TSP_SETDATE */ diff --git a/unused/itca.jpg b/unused/itca.jpg new file mode 100644 index 000000000000..89a7119c0ccc Binary files /dev/null and b/unused/itca.jpg differ diff --git a/unused/newctime.3 b/unused/newctime.3 new file mode 100644 index 000000000000..323201e0c506 --- /dev/null +++ b/unused/newctime.3 @@ -0,0 +1,239 @@ +.TH NEWCTIME 3 +.SH NAME +asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time to ASCII +.SH SYNOPSIS +.nf +.B extern char *tzname[2]; +.PP +.B void tzset() +.PP +.B #include +.PP +.B char *ctime(clock) +.B const time_t *clock; +.PP +.B double difftime(time1, time0) +.B time_t time1; +.B time_t time0; +.PP +.B #include +.PP +.B char *asctime(tm) +.B const struct tm *tm; +.PP +.B struct tm *localtime(clock) +.B const time_t *clock; +.PP +.B struct tm *gmtime(clock) +.B const time_t *clock; +.PP +.B time_t mktime(tm) +.B struct tm *tm; +.PP +.B cc ... -ltz +.fi +.SH DESCRIPTION +.I Ctime\^ +converts a long integer, pointed to by +.IR clock , +representing the time in seconds since +00:00:00 UTC, 1970-01-01, +and returns a pointer to a +string of the form +.br +.ce +.eo +Thu Nov 24 18:22:48 1986\n\0 +.br +.ec +Years requiring fewer than four characters are padded with leading zeroes. +For years longer than four characters, the string is of the form +.br +.ce +.eo +Thu Nov 24 18:22:48 81986\n\0 +.ec +.br +with five spaces before the year. +These unusual formats are designed to make it less likely that older +software that expects exactly 26 bytes of output will mistakenly output +misleading values for out-of-range years. +.PP +.I Localtime\^ +and +.I gmtime\^ +return pointers to ``tm'' structures, described below. +.I Localtime\^ +corrects for the time zone and any time zone adjustments +(such as Daylight Saving Time in the United States). +After filling in the ``tm'' structure, +.I localtime +sets the +.BR tm_isdst 'th +element of +.B tzname +to a pointer to an +ASCII string that's the time zone abbreviation to be used with +.IR localtime 's +return value. +.PP +.I Gmtime\^ +converts to Coordinated Universal Time. +.PP +.I Asctime\^ +converts a time value contained in a +``tm'' structure to a string, +as shown in the above example, +and returns a pointer to the string. +.PP +.I Mktime\^ +converts the broken-down time, +expressed as local time, +in the structure pointed to by +.I tm +into a calendar time value with the same encoding as that of the values +returned by the +.I time +function. +The original values of the +.B tm_wday +and +.B tm_yday +components of the structure are ignored, +and the original values of the other components are not restricted +to their normal ranges. +(A positive or zero value for +.B tm_isdst +causes +.I mktime +to presume initially that summer time (for example, Daylight Saving Time +in the U.S.A.) +respectively, +is or is not in effect for the specified time. +A negative value for +.B tm_isdst +causes the +.I mktime +function to attempt to divine whether summer time is in effect +for the specified time; in this case it does not use a consistent +rule and may give a different answer when later +presented with the same argument.) +On successful completion, the values of the +.B tm_wday +and +.B tm_yday +components of the structure are set appropriately, +and the other components are set to represent the specified calendar time, +but with their values forced to their normal ranges; the final value of +.B tm_mday +is not set until +.B tm_mon +and +.B tm_year +are determined. +.I Mktime\^ +returns the specified calendar time; +If the calendar time cannot be represented, +it returns +.BR -1 . +.PP +.I Difftime\^ +returns the difference between two calendar times, +.RI ( time1 +- +.IR time0 ), +expressed in seconds. +.PP +Declarations of all the functions and externals, and the ``tm'' structure, +are in the +.B \^ +header file. +The structure (of type) +.B struct tm +includes the following fields: +.RS +.PP +.nf +.ta .5i +\w'long tm_gmtoff;\0\0'u + int tm_sec; /\(** seconds (0 - 60) \(**/ + int tm_min; /\(** minutes (0 - 59) \(**/ + int tm_hour; /\(** hours (0 - 23) \(**/ + int tm_mday; /\(** day of month (1 - 31) \(**/ + int tm_mon; /\(** month of year (0 - 11) \(**/ + int tm_year; /\(** year \- 1900 \(**/ + int tm_wday; /\(** day of week (Sunday = 0) \(**/ + int tm_yday; /\(** day of year (0 - 365) \(**/ + int tm_isdst; /\(** is summer time in effect? \(**/ + char \(**tm_zone; /\(** abbreviation of timezone name \(**/ + long tm_gmtoff; /\(** offset from UTC in seconds \(**/ +.fi +.RE +.PP +The +.I tm_zone +and +.I tm_gmtoff +fields exist, and are filled in, only if arrangements to do +so were made when the library containing these functions was +created. +There is no guarantee that these fields will continue to exist +in this form in future releases of this code. +.PP +.I Tm_isdst\^ +is non-zero if summer time is in effect. +.PP +.I Tm_gmtoff +is the offset (in seconds) of the time represented +from UTC, with positive values indicating east +of the Prime Meridian. +.SH FILES +.ta \w'/usr/local/etc/zoneinfo/posixrules\0\0'u +/usr/local/etc/zoneinfo time zone information directory +.br +/usr/local/etc/zoneinfo/localtime local time zone file +.br +/usr/local/etc/zoneinfo/posixrules used with POSIX-style TZ's +.br +/usr/local/etc/zoneinfo/GMT for UTC leap seconds +.sp +If +.B /usr/local/etc/zoneinfo/GMT +is absent, +UTC leap seconds are loaded from +.BR /usr/local/etc/zoneinfo/posixrules . +.SH SEE ALSO +getenv(3), +newstrftime(3), +newtzset(3), +time(2), +tzfile(5) +.SH NOTES +The return values point to static data; +the data is overwritten by each call. +The +.B tm_zone +field of a returned +.B "struct tm" +points to a static array of characters, which +will also be overwritten at the next call +(and by calls to +.IR tzset ). +.PP +.I Asctime\^ +and +.I ctime\^ +behave strangely for years before 1000 or after 9999. +The 1989 and 1999 editions of the C Standard say +that years from \-99 through 999 are converted without +extra spaces, but this conflicts with longstanding +tradition and with this implementation. +Traditional implementations of these two functions are +restricted to years in the range 1900 through 2099. +To avoid this portability mess, new programs should use +.I strftime\^ +instead. +.PP +Avoid using out-of-range values with +.I mktime +when setting up lunch with promptness sticklers in Riyadh. +.\" @(#)newctime.3 8.2 diff --git a/unused/newctime.3.txt b/unused/newctime.3.txt new file mode 100644 index 000000000000..ba311400474a --- /dev/null +++ b/unused/newctime.3.txt @@ -0,0 +1,149 @@ +NAME + + asctime, ctime, difftime, gmtime, localtime, mktime - + convert date and time to ASCII + +SYNOPSIS + extern char *tzname[2]; + + void tzset() + + #include + + char *ctime(clock) + const time_t *clock; + + double difftime(time1, time0) + time_t time1; + time_t time0; + + #include + + char *asctime(tm) + const struct tm *tm; + + struct tm *localtime(clock) + const time_t *clock; + + struct tm *gmtime(clock) + const time_t *clock; + + time_t mktime(tm) + struct tm *tm; + + cc ... -ltz + +DESCRIPTION + Ctime converts a long integer, pointed to by clock, + representing the time in seconds since 00:00:00 UTC, + 1970-01-01, and returns a pointer to a string of the form + Thu Nov 24 18:22:48 1986\n\0 + Years requiring fewer than four characters are padded with + leading zeroes. For years longer than four characters, the + string is of the form + Thu Nov 24 18:22:48 81986\n\0 + with five spaces before the year. These unusual formats are + designed to make it less likely that older software that + expects exactly 26 bytes of output will mistakenly output + misleading values for out-of-range years. + + Localtime and gmtime return pointers to ``tm'' structures, + described below. Localtime corrects for the time zone and + any time zone adjustments (such as Daylight Saving Time in + the United States). After filling in the ``tm'' structure, + localtime sets the tm_isdst'th element of tzname to a + pointer to an ASCII string that's the time zone abbreviation + to be used with localtime's return value. + + Gmtime converts to Coordinated Universal Time. + + Asctime converts a time value contained in a ``tm'' + structure to a string, as shown in the above example, and + returns a pointer to the string. + + Mktime converts the broken-down time, expressed as local + time, in the structure pointed to by tm into a calendar time + value with the same encoding as that of the values returned + by the time function. The original values of the tm_wday + and tm_yday components of the structure are ignored, and the + original values of the other components are not restricted + to their normal ranges. (A positive or zero value for + tm_isdst causes mktime to presume initially that summer time + (for example, Daylight Saving Time in the U.S.A.) + respectively, is or is not in effect for the specified time. + A negative value for tm_isdst causes the mktime function to + attempt to divine whether summer time is in effect for the + specified time; in this case it does not use a consistent + rule and may give a different answer when later presented + with the same argument.) On successful completion, the + values of the tm_wday and tm_yday components of the + structure are set appropriately, and the other components + are set to represent the specified calendar time, but with + their values forced to their normal ranges; the final value + of tm_mday is not set until tm_mon and tm_year are + determined. Mktime returns the specified calendar time; If + the calendar time cannot be represented, it returns -1. + + Difftime returns the difference between two calendar times, + (time1 - time0), expressed in seconds. + + Declarations of all the functions and externals, and the + ``tm'' structure, are in the header file. The + structure (of type) struct tm includes the following fields: + + int tm_sec; /* seconds (0 - 60) */ + int tm_min; /* minutes (0 - 59) */ + int tm_hour; /* hours (0 - 23) */ + int tm_mday; /* day of month (1 - 31) */ + int tm_mon; /* month of year (0 - 11) */ + int tm_year; /* year - 1900 */ + int tm_wday; /* day of week (Sunday = 0) */ + int tm_yday; /* day of year (0 - 365) */ + int tm_isdst; /* is summer time in effect? */ + char *tm_zone; /* abbreviation of timezone name */ + long tm_gmtoff; /* offset from UTC in seconds */ + + The tm_zone and tm_gmtoff fields exist, and are filled in, + only if arrangements to do so were made when the library + containing these functions was created. There is no + guarantee that these fields will continue to exist in this + form in future releases of this code. + + Tm_isdst is non-zero if summer time is in effect. + + Tm_gmtoff is the offset (in seconds) of the time represented + from UTC, with positive values indicating east of the Prime + Meridian. + +FILES + /usr/local/etc/zoneinfo time zone information + directory + /usr/local/etc/zoneinfo/localtime local time zone file + /usr/local/etc/zoneinfo/posixrules used with POSIX-style + TZ's + /usr/local/etc/zoneinfo/GMT for UTC leap seconds + + If /usr/local/etc/zoneinfo/GMT is absent, UTC leap seconds + are loaded from /usr/local/etc/zoneinfo/posixrules. + +SEE ALSO + getenv(3), newstrftime(3), newtzset(3), time(2), tzfile(5) + +NOTES + The return values point to static data; the data is + overwritten by each call. The tm_zone field of a returned + struct tm points to a static array of characters, which will + also be overwritten at the next call (and by calls to + tzset). + + Asctime and ctime behave strangely for years before 1000 or + after 9999. The 1989 and 1999 editions of the C Standard + say that years from -99 through 999 are converted without + extra spaces, but this conflicts with longstanding tradition + and with this implementation. Traditional implementations + of these two functions are restricted to years in the range + 1900 through 2099. To avoid this portability mess, new + programs should use strftime instead. + + Avoid using out-of-range values with mktime when setting up + lunch with promptness sticklers in Riyadh. diff --git a/unused/newstrftime.3 b/unused/newstrftime.3 new file mode 100644 index 000000000000..92392dcc3264 --- /dev/null +++ b/unused/newstrftime.3 @@ -0,0 +1,230 @@ +.\" Based on the UCB file whose copyright information appears below. +.\" Copyright (c) 1989, 1991 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" from: @(#)strftime.3 5.12 (Berkeley) 6/29/91 +.\" $Id: strftime.3,v 1.4 1993/12/15 20:33:00 jtc Exp $ +.\" +.TH NEWSTRFTIME 3 +.SH NAME +strftime \- format date and time +.SH SYNOPSIS +.nf +.B #include +.B #include +.PP +.B size_t strftime(buf, maxsize, format, timeptr) +.B char *buf; +.B size_t maxsize; +.B const char *format; +.B const struct tm *timeptr +.PP +.B cc ... -ltz +.fi +.SH DESCRIPTION +The +.I strftime\^ +function formats the information from +.I timeptr\^ +into the buffer +.I buf\^ +according to the string pointed to by +.IR format\^ . +.PP +The +.I format\^ +string consists of zero or more conversion specifications and +ordinary characters. +All ordinary characters are copied directly into the buffer. +A conversion specification consists of a percent sign +.Ql % +and one other character. +.PP +No more than +.I maxsize\^ +characters are be placed into the array. +If the total number of resulting characters, including the terminating +null character, is not more than +.IR maxsize\^ , +.I strftime\^ +returns the number of characters in the array, not counting the +terminating null. +Otherwise, zero is returned. +.PP +Each conversion specification is replaced by the characters as +follows which are then copied into the buffer. +.TP +%A +is replaced by the locale's full weekday name. +.TP +%a +is replaced by the locale's abbreviated weekday name. +.TP +%B +is replaced by the locale's full month name. +.TP +%b or %h +is replaced by the locale's abbreviated month name. +.TP +%C +is replaced by the century (a year divided by 100 and truncated to an integer) +as a decimal number (00-99). +.TP +%c +is replaced by the locale's appropriate date and time representation. +.TP +%D +is replaced by the date in the format %m/%d/%y. +.TP +%d +is replaced by the day of the month as a decimal number (01-31). +.TP +%e +is replaced by the day of month as a decimal number (1-31); +single digits are preceded by a blank. +.TP +%F +is replaced by the date in the format %Y-%m-%d. +.TP +%G +is replaced by the ISO 8601 year with century as a decimal number. +.TP +%g +is replaced by the ISO 8601 year without century as a decimal number (00-99). +.TP +%H +is replaced by the hour (24-hour clock) as a decimal number (00-23). +.TP +%I +is replaced by the hour (12-hour clock) as a decimal number (01-12). +.TP +%j +is replaced by the day of the year as a decimal number (001-366). +.TP +%k +is replaced by the hour (24-hour clock) as a decimal number (0-23); +single digits are preceded by a blank. +.TP +%l +is replaced by the hour (12-hour clock) as a decimal number (1-12); +single digits are preceded by a blank. +.TP +%M +is replaced by the minute as a decimal number (00-59). +.TP +%m +is replaced by the month as a decimal number (01-12). +.TP +%n +is replaced by a newline. +.TP +%p +is replaced by the locale's equivalent of either AM or PM. +.TP +%R +is replaced by the time in the format %H:%M. +.TP +%r +is replaced by the locale's representation of 12-hour clock time +using AM/PM notation. +.TP +%S +is replaced by the second as a decimal number (00-60). +.TP +%s +is replaced by the number of seconds since the Epoch, UTC (see mktime(3)). +.TP +%T +is replaced by the time in the format %H:%M:%S. +.TP +%t +is replaced by a tab. +.TP +%U +is replaced by the week number of the year (Sunday as the first day of +the week) as a decimal number (00-53). +.TP +%u +is replaced by the weekday (Monday as the first day of the week) +as a decimal number (1-7). +.TP +%V +is replaced by the week number of the year (Monday as the first day of +the week) as a decimal number (01-53). If the week containing January +1 has four or more days in the new year, then it is week 1; otherwise +it is week 53 of the previous year, and the next week is week 1. +.TP +%W +is replaced by the week number of the year (Monday as the first day of +the week) as a decimal number (00-53). +.TP +%w +is replaced by the weekday (Sunday as the first day of the week) +as a decimal number (0-6). +.TP +%X +is replaced by the locale's appropriate time representation. +.TP +%x +is replaced by the locale's appropriate date representation. +.TP +%Y +is replaced by the year with century as a decimal number. +.TP +%y +is replaced by the year without century as a decimal number (00-99). +.TP +%Z +is replaced by the time zone name, +or by the empty string if this is not determinable. +.TP +%z +is replaced by the offset from UTC in the format +HHMM or -HHMM as appropriate, +with positive values representing locations east of Greenwich, +or by the empty string if this is not determinable. +.TP +%% +is replaced by a single %. +.TP +%+ +is replaced by the date and time in date(1) format. +.SH SEE ALSO +date(1), +getenv(3), +newctime(3), +newtzset(3), +time(2), +tzfile(5) +.\" @(#)newstrftime.3 8.1 diff --git a/unused/newstrftime.3.txt b/unused/newstrftime.3.txt new file mode 100644 index 000000000000..ea210a869f4a --- /dev/null +++ b/unused/newstrftime.3.txt @@ -0,0 +1,149 @@ +NAME + + strftime - format date and time + +SYNOPSIS + #include + #include + + size_t strftime(buf, maxsize, format, timeptr) + char *buf; + size_t maxsize; + const char *format; + const struct tm *timeptr + + cc ... -ltz + +DESCRIPTION + The strftime function formats the information from timeptr + into the buffer buf according to the string pointed to by + format. + + The format string consists of zero or more conversion + specifications and ordinary characters. All ordinary + characters are copied directly into the buffer. A + conversion specification consists of a percent sign and one + other character. + + No more than maxsize characters are be placed into the + array. If the total number of resulting characters, + including the terminating null character, is not more than + maxsize, strftime returns the number of characters in the + array, not counting the terminating null. Otherwise, zero + is returned. + + Each conversion specification is replaced by the characters + as follows which are then copied into the buffer. + + %A is replaced by the locale's full weekday name. + + %a is replaced by the locale's abbreviated weekday name. + + %B is replaced by the locale's full month name. + + %b or %h + is replaced by the locale's abbreviated month name. + + %C is replaced by the century (a year divided by 100 and + truncated to an integer) as a decimal number (00-99). + + %c is replaced by the locale's appropriate date and time + representation. + + %D is replaced by the date in the format %m/%d/%y. + + %d is replaced by the day of the month as a decimal number + (01-31). + + %e is replaced by the day of month as a decimal number + (1-31); single digits are preceded by a blank. + %F is replaced by the date in the format %Y-%m-%d. + + %G is replaced by the ISO 8601 year with century as a + decimal number. + + %g is replaced by the ISO 8601 year without century as a + decimal number (00-99). + %H is replaced by the hour (24-hour clock) as a decimal + number (00-23). + + %I is replaced by the hour (12-hour clock) as a decimal + number (01-12). + + %j is replaced by the day of the year as a decimal number + (001-366). + + %k is replaced by the hour (24-hour clock) as a decimal + number (0-23); single digits are preceded by a blank. + + %l is replaced by the hour (12-hour clock) as a decimal + number (1-12); single digits are preceded by a blank. + + %M is replaced by the minute as a decimal number (00-59). + + %m is replaced by the month as a decimal number (01-12). + + %n is replaced by a newline. + + %p is replaced by the locale's equivalent of either AM or + PM. + + %R is replaced by the time in the format %H:%M. + + %r is replaced by the locale's representation of 12-hour + clock time using AM/PM notation. + + %S is replaced by the second as a decimal number (00-60). + + %s is replaced by the number of seconds since the Epoch, + UTC (see mktime(3)). + + %T is replaced by the time in the format %H:%M:%S. + + %t is replaced by a tab. + + %U is replaced by the week number of the year (Sunday as + the first day of the week) as a decimal number (00-53). + + %u is replaced by the weekday (Monday as the first day of + the week) as a decimal number (1-7). + + %V is replaced by the week number of the year (Monday as + the first day of the week) as a decimal number (01-53). + If the week containing January 1 has four or more days + in the new year, then it is week 1; otherwise it is + week 53 of the previous year, and the next week is week + 1. + + %W is replaced by the week number of the year (Monday as + the first day of the week) as a decimal number (00-53). + + %w is replaced by the weekday (Sunday as the first day of + the week) as a decimal number (0-6). + + %X is replaced by the locale's appropriate time + representation. + %x is replaced by the locale's appropriate date + representation. + + %Y is replaced by the year with century as a decimal + number. + + %y is replaced by the year without century as a decimal + number (00-99). + + %Z is replaced by the time zone name, or by the empty + string if this is not determinable. + + %z is replaced by the offset from UTC in the format +HHMM + or -HHMM as appropriate, with positive values + representing locations east of Greenwich, or by the + empty string if this is not determinable. + + %% is replaced by a single %. + + %+ is replaced by the date and time in date(1) format. + +SEE ALSO + date(1), getenv(3), newctime(3), newtzset(3), time(2), + tzfile(5) diff --git a/unused/newtzset.3 b/unused/newtzset.3 new file mode 100644 index 000000000000..e19ad7033e16 --- /dev/null +++ b/unused/newtzset.3 @@ -0,0 +1,237 @@ +.TH NEWTZSET 3 +.SH NAME +tzset \- initialize time conversion information +.SH SYNOPSIS +.nf +.B void tzset() +.PP +.B cc ... -ltz +.fi +.SH DESCRIPTION +.I Tzset +uses the value of the environment variable +.B TZ +to set time conversion information used by +.IR localtime . +If +.B TZ +does not appear in the environment, +the best available approximation to local wall clock time, as specified +by the +.IR tzfile (5)-format +file +.B localtime +in the system time conversion information directory, is used by +.IR localtime . +If +.B TZ +appears in the environment but its value is a null string, +Coordinated Universal Time (UTC) is used (without leap second +correction). If +.B TZ +appears in the environment and its value is not a null string: +.IP +if the value begins with a colon, it is used as a pathname of a file +from which to read the time conversion information; +.IP +if the value does not begin with a colon, it is first used as the +pathname of a file from which to read the time conversion information, +and, if that file cannot be read, is used directly as a specification of +the time conversion information. +.PP +When +.B TZ +is used as a pathname, if it begins with a slash, +it is used as an absolute pathname; otherwise, +it is used as a pathname relative to a system time conversion information +directory. +The file must be in the format specified in +.IR tzfile (5). +.PP +When +.B TZ +is used directly as a specification of the time conversion information, +it must have the following syntax (spaces inserted for clarity): +.IP +\fIstd\|offset\fR[\fIdst\fR[\fIoffset\fR][\fB,\fIrule\fR]] +.PP +Where: +.RS +.TP 15 +.IR std " and " dst +Three or more bytes that are the designation for the standard +.RI ( std ) +or summer +.RI ( dst ) +time zone. Only +.I std +is required; if +.I dst +is missing, then summer time does not apply in this locale. +Upper- and lowercase letters are explicitly allowed. Any characters +except a leading colon +.RB ( : ), +digits, comma +.RB ( , ), +minus +.RB ( \(mi ), +plus +.RB ( \(pl ), +and ASCII NUL are allowed. +.TP +.I offset +Indicates the value one must add to the local time to arrive at +Coordinated Universal Time. The +.I offset +has the form: +.RS +.IP +\fIhh\fR[\fB:\fImm\fR[\fB:\fIss\fR]] +.RE +.IP +The minutes +.RI ( mm ) +and seconds +.RI ( ss ) +are optional. The hour +.RI ( hh ) +is required and may be a single digit. The +.I offset +following +.I std +is required. If no +.I offset +follows +.IR dst , +summer time is assumed to be one hour ahead of standard time. One or +more digits may be used; the value is always interpreted as a decimal +number. The hour must be between zero and 24, and the minutes (and +seconds) \(em if present \(em between zero and 59. If preceded by a +.RB `` \(mi '', +the time zone shall be east of the Prime Meridian; otherwise it shall be +west (which may be indicated by an optional preceding +.RB `` \(pl ''). +.TP +.I rule +Indicates when to change to and back from summer time. The +.I rule +has the form: +.RS +.IP +\fIdate\fB/\fItime\fB,\fIdate\fB/\fItime\fR +.RE +.IP +where the first +.I date +describes when the change from standard to summer time occurs and the +second +.I date +describes when the change back happens. Each +.I time +field describes when, in current local time, the change to the other +time is made. +.IP +The format of +.I date +is one of the following: +.RS +.TP 10 +.BI J n +The Julian day +.I n +.RI "(1\ \(<=" "\ n\ " "\(<=\ 365). +Leap days are not counted; that is, in all years \(em including leap +years \(em February 28 is day 59 and March 1 is day 60. It is +impossible to explicitly refer to the occasional February 29. +.TP +.I n +The zero-based Julian day +.RI "(0\ \(<=" "\ n\ " "\(<=\ 365). +Leap days are counted, and it is possible to refer to February 29. +.TP +.BI M m . n . d +The +.IR d' th +day +.RI "(0\ \(<=" "\ d\ " "\(<=\ 6) +of week +.I n +of month +.I m +of the year +.RI "(1\ \(<=" "\ n\ " "\(<=\ 5, +.RI "1\ \(<=" "\ m\ " "\(<=\ 12, +where week 5 means ``the last +.I d +day in month +.IR m '' +which may occur in either the fourth or the fifth week). Week 1 is the +first week in which the +.IR d' th +day occurs. Day zero is Sunday. +.RE +.IP "" 15 +The +.I time +has the same format as +.I offset +except that no leading sign +.RB (`` \(mi '' +or +.RB `` \(pl '') +is allowed. The default, if +.I time +is not given, is +.BR 02:00:00 . +.RE +.LP +If no +.I rule +is present in +.BR TZ , +the rules specified +by the +.IR tzfile (5)-format +file +.B posixrules +in the system time conversion information directory are used, with the +standard and summer time offsets from UTC replaced by those specified by +the +.I offset +values in +.BR TZ . +.PP +For compatibility with System V Release 3.1, a semicolon +.RB ( ; ) +may be used to separate the +.I rule +from the rest of the specification. +.PP +If the +.B TZ +environment variable does not specify a +.IR tzfile (5)-format +and cannot be interpreted as a direct specification, +UTC is used. +.SH FILES +.ta \w'/usr/local/etc/zoneinfo/posixrules\0\0'u +/usr/local/etc/zoneinfo time zone information directory +.br +/usr/local/etc/zoneinfo/localtime local time zone file +.br +/usr/local/etc/zoneinfo/posixrules used with POSIX-style TZ's +.br +/usr/local/etc/zoneinfo/GMT for UTC leap seconds +.sp +If +.B /usr/local/etc/zoneinfo/GMT +is absent, +UTC leap seconds are loaded from +.BR /usr/local/etc/zoneinfo/posixrules . +.SH SEE ALSO +getenv(3), +newctime(3), +newstrftime(3), +time(2), +tzfile(5) +.\" @(#)newtzset.3 8.1 diff --git a/unused/newtzset.3.txt b/unused/newtzset.3.txt new file mode 100644 index 000000000000..9d7d02233ee0 --- /dev/null +++ b/unused/newtzset.3.txt @@ -0,0 +1,153 @@ +NAME + + tzset - initialize time conversion information + +SYNOPSIS + void tzset() + + cc ... -ltz + +DESCRIPTION + Tzset uses the value of the environment variable TZ to set + time conversion information used by localtime. If TZ does + not appear in the environment, the best available + approximation to local wall clock time, as specified by the + tzfile(5)-format file localtime in the system time + conversion information directory, is used by localtime. If + TZ appears in the environment but its value is a null + string, Coordinated Universal Time (UTC) is used (without + leap second correction). If TZ appears in the environment + and its value is not a null string: + + if the value begins with a colon, it is used as a + pathname of a file from which to read the time + conversion information; + + if the value does not begin with a colon, it is first + used as the pathname of a file from which to read the + time conversion information, and, if that file cannot + be read, is used directly as a specification of the + time conversion information. + + When TZ is used as a pathname, if it begins with a slash, it + is used as an absolute pathname; otherwise, it is used as a + pathname relative to a system time conversion information + directory. The file must be in the format specified in + tzfile(5). + + When TZ is used directly as a specification of the time + conversion information, it must have the following syntax + (spaces inserted for clarity): + + stdoffset[dst[offset][,rule]] + + Where: + + std and dst Three or more bytes that are the + designation for the standard (std) or + summer (dst) time zone. Only std is + required; if dst is missing, then summer + time does not apply in this locale. + Upper- and lowercase letters are + explicitly allowed. Any characters + except a leading colon (:), digits, + comma (,), minus (-), plus (+), and + ASCII NUL are allowed. + + offset Indicates the value one must add to the + local time to arrive at Coordinated + Universal Time. The offset has the + form: + + hh[:mm[:ss]] + + The minutes (mm) and seconds (ss) are + optional. The hour (hh) is required and + may be a single digit. The offset + following std is required. If no offset + follows dst, summer time is assumed to + be one hour ahead of standard time. One + or more digits may be used; the value is + always interpreted as a decimal number. + The hour must be between zero and 24, + and the minutes (and seconds) -- if + present -- between zero and 59. If + preceded by a ``-'', the time zone shall + be east of the Prime Meridian; otherwise + it shall be west (which may be indicated + by an optional preceding ``+''). + + rule Indicates when to change to and back + from summer time. The rule has the + form: + + date/time,date/time + + where the first date describes when the + change from standard to summer time + occurs and the second date describes + when the change back happens. Each time + field describes when, in current local + time, the change to the other time is + made. + + The format of date is one of the + following: + + Jn The Julian day n + (1 <= n <= 365). Leap days + are not counted; that is, in + all years -- including leap + years -- February 28 is day 59 + and March 1 is day 60. It is + impossible to explicitly refer + to the occasional February 29. + + n The zero-based Julian day + (0 <= n <= 365). Leap days + are counted, and it is + possible to refer to February + 29. + + Mm.n.d The d'th day (0 <= d <= 6) of + week n of month m of the year + (1 <= n <= 5, 1 <= m <= 12, + where week 5 means ``the last + d day in month m'' which may + occur in either the fourth or + the fifth week). Week 1 is + the first week in which the + d'th day occurs. Day zero is + Sunday. + + The time has the same format as offset + except that no leading sign (``-'' or + ``+'') is allowed. The default, if time + is not given, is 02:00:00. + + If no rule is present in TZ, the rules specified by the + tzfile(5)-format file posixrules in the system time + conversion information directory are used, with the standard + and summer time offsets from UTC replaced by those specified + by the offset values in TZ. + For compatibility with System V Release 3.1, a semicolon (;) + may be used to separate the rule from the rest of the + specification. + + If the TZ environment variable does not specify a + tzfile(5)-format and cannot be interpreted as a direct + specification, UTC is used. + +FILES + /usr/local/etc/zoneinfo time zone information + directory + /usr/local/etc/zoneinfo/localtime local time zone file + /usr/local/etc/zoneinfo/posixrules used with POSIX-style + TZ's + /usr/local/etc/zoneinfo/GMT for UTC leap seconds + + If /usr/local/etc/zoneinfo/GMT is absent, UTC leap seconds + are loaded from /usr/local/etc/zoneinfo/posixrules. + +SEE ALSO + getenv(3), newctime(3), newstrftime(3), time(2), tzfile(5) diff --git a/unused/time2posix.3.txt b/unused/time2posix.3.txt new file mode 100644 index 000000000000..1bcf168e2e6c --- /dev/null +++ b/unused/time2posix.3.txt @@ -0,0 +1,83 @@ +NAME + + time2posix, posix2time - convert seconds since the Epoch + +SYNOPSIS + #include + #include + + time_t time2posix(t) + time_t t + + time_t posix2time(t) + time_t t + + cc ... -ltz + +DESCRIPTION + IEEE Standard 1003.1 (POSIX) legislates that a time_t value + of 536457599 shall correspond to "Wed Dec 31 23:59:59 UTC + 1986." This effectively implies that POSIX time_t's cannot + include leap seconds and, therefore, that the system time + must be adjusted as each leap occurs. + + If the time package is configured with leap-second support + enabled, however, no such adjustment is needed and time_t + values continue to increase over leap events (as a true + `seconds since...' value). This means that these values + will differ from those required by POSIX by the net number + of leap seconds inserted since the Epoch. + + Typically this is not a problem as the type time_t is + intended to be (mostly) opaque--time_t values should only be + obtained-from and passed-to functions such as time(2), + localtime(3), mktime(3), and difftime(3). However, POSIX + gives an arithmetic expression for directly computing a + time_t value from a given date/time, and the same + relationship is assumed by some (usually older) + applications. Any programs creating/dissecting time_t's + using such a relationship will typically not handle + intervals over leap seconds correctly. + + The time2posix and posix2time functions are provided to + address this time_t mismatch by converting between local + time_t values and their POSIX equivalents. This is done by + accounting for the number of time-base changes that would + have taken place on a POSIX system as leap seconds were + inserted or deleted. These converted values can then be + used in lieu of correcting the older applications, or when + communicating with POSIX-compliant systems. + + Time2posix is single-valued. That is, every local time_t + corresponds to a single POSIX time_t. Posix2time is less + well-behaved: for a positive leap second hit the result is + not unique, and for a negative leap second hit the + corresponding POSIX time_t doesn't exist so an adjacent + value is returned. Both of these are good indicators of the + inferiority of the POSIX representation. + + The following table summarizes the relationship between a + time T and it's conversion to, and back from, the POSIX + representation over the leap second inserted at the end of + June, 1993. + DATE TIME T X=time2posix(T) posix2time(X) + 93/06/30 23:59:59 A+0 B+0 A+0 + 93/06/30 23:59:60 A+1 B+1 A+1 or A+2 + 93/07/01 00:00:00 A+2 B+1 A+1 or A+2 + 93/07/01 00:00:01 A+3 B+2 A+3 + + A leap second deletion would look like... + + DATE TIME T X=time2posix(T) posix2time(X) + ??/06/30 23:59:58 A+0 B+0 A+0 + ??/07/01 00:00:00 A+1 B+2 A+1 + ??/07/01 00:00:01 A+2 B+3 A+2 + + [Note: posix2time(B+1) => A+0 or A+1] + + If leap-second support is not enabled, local time_t's and + POSIX time_t's are equivalent, and both time2posix and + posix2time degenerate to the identity function. + +SEE ALSO + difftime(3), localtime(3), mktime(3), time(2) diff --git a/zic/tz-art.htm b/unused/tz-art.htm similarity index 65% rename from zic/tz-art.htm rename to unused/tz-art.htm index 56f78ace2e0d..352c408b66cb 100644 --- a/zic/tz-art.htm +++ b/unused/tz-art.htm @@ -1,23 +1,22 @@ - - - + + - + Time and the Arts

Time and the Arts

-@(#)tz-art.htm 7.53 +@(#)tz-art.htm 8.11

Please send corrections to this web page to the time zone mailing list.

See also Sources for Time Zone and Daylight Saving Time Data.

-
+

Data on recordings of "Save That Time," Russ Long, Serrob Publishing, BMI:

@@ -83,7 +82,7 @@ Marion Simon, percussion
AMG Ratingunrated
Penguin Rating3 stars
-
+

Also of note:

@@ -160,6 +159,99 @@ Richard Teitelbaum, modular moog and micromoog synthesizer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -173,13 +265,40 @@ is available at http://fourmilab.ch/etexts/www/tdm80j An on-line English-language translation of the book is available at http://www.literature.org/Works/Jules-Verne/eighty + + + + + + + + + + + + + + + - +
ArtistHolly Cole Trio
ADO Ratingblack dot
AMG Ratingunrated
 
ArtistCharles Gayle
CDTime Zones
Copyright Date2006
LabelTompkins Square
IDTSQ2839
Total Time49:06
PersonnelCharles Gayle, piano
ADO Rating1 star
AMG Rating4.5 stars
 
ArtistThe Get Up Kids
CDEudora
Copyright Date2001
LabelVagrant
ID357
Total Time65:12
NotesIncludes the song "Central Standard Time." Thanks to Colin Bowern for this information.
AMG Rating2.5 stars
 
ArtistColdplay
SongClocks
Copyright Date2003
LabelCapitol Records
ID52608
Total Time4:13
NotesWon the 2004 Record of the Year honor at the +Grammy Awards. Co-written and performed by Chris Martin, +great-great-grandson of DST inventor William Willett. The song's first +line is "Lights go out and I can't be saved".
 
ArtistIrving Kahal and Harry Richman
SongThere Ought to be a Moonlight Saving Time
Copyright Date1931
NotesThis musical standard was a #1 hit for Guy Lombardo +in 1931, and was also performed by Maurice Chevalier, Blossom Dearie +and many others. The phrase "Moonlight saving time" also appears in +the 1995 country song "Not Enough Hours in the Night" written by Aaron +Barker, Kim Williams and Rob Harbin and performed by Doug +Supernaw.
 
ArtistThe Microscopic Septet
CDLobster Leaps In
Copyright Date2008
LabelCuneiform
ID272
Total Time73:05
NotesIncludes the song "Twilight Time Zone."
AMG Rating3.5 stars
ADO Rating2 stars
 
ArtistBob Dylan
CDThe Time They Are A-Changin'
Copyright Date1964
LabelColumbia
IDCK-8905
Total Time45:36
AMG Rating4.5 stars
ADO Rating1.5 stars
NotesThe title song is also available on "Bob Dylan's Greatest Hits" and "The Essential Bob Dylan."
 
TV episode titleThe Lost Hour
TV seriesEerie, Indiana
TV episode number10
NetworkNBC
Air date1991-12-01
NotesDespite Indiana's then-lack of DST, Marshall changes his clock with unusual consequences.
 
TV episode titleTime Tunnel
TV seriesThe Adventures of Pete & Pete
TV episode number5, season 2
NetworkNickelodeon
Air date1994-10-23
NotesThe two Petes travel back in time an hour on the day that DST ends.
 
TV episode titleKing-Size Homer
TV seriesThe Simpsons
TV episode number135
NetworkFox
Air date1995-11-05
NotesHomer, working from home, remarks "8:58, first +time I've ever been early for work. Except for all those daylight +savings days. Lousy farmers."
 
ArtistJules Verne
BookLe Tour du Monde en Quatre-Vingts Jours (Around the World in Eighty Days)
 
ArtistUmberto Eco
BookThe Island of the Day Before +(L'isola del giorno prima)
Copyright Date1994
Notes +"...the story of a 17th century Italian nobleman trapped near an island +on the International Date Line. Time and time zones play an integral +part in the novel." (Paul Eggert, 2006-04-22) +
 
ArtistDavid Jebb
Book +The Thirteenth Time Zone
Notes +"It's fiction, but it's based on his experiences and travels." (Paul Eggert, 2006-04-22) +
 
ArtistJohn Dunning
BookTwo +O'Clock, Eastern Wartime
Copyright Date2001
Notes +Mystery, history, daylight saving time, and old-time radio. +
 
FilmBell Science - About Time
NotesThe Frank Baxter/Richard Deacon extravaganza -Information on ordering is available at -http://www.videoflicks.com/VF2/1035/1035893.ihtml
NotesThe Frank Baxter/Richard Deacon extravaganza. +Information is available at +http://www.videoflicks.com/titles/1035/1035893.htm
-
+
  • An episode of "The Adventures of Superman" entitled "The Mysterious @@ -225,14 +344,19 @@ zones?" was a $32,000 question on the 2001-05-23 United States airing of "Who Wants to Be a Millionaire?" At this rate, the million-dollar time-zone question should have been asked 2002-06-04.
  • +
  • +A private jet's mid-flight change of time zones distorts Alison Dubois' +premonition in the "We Had a Dream" episode of "Medium" +(originally aired 2007-02-28). +
-
+
  • "We're been using the five-cent nickle in this country since 1492. Now that's pretty near 100 years, daylight savings [sic]." (Groucho Marx as Captain Spaulding in "Animal Crackers", 1930, -as noted by Will Fitzerald, wfitzgerald@ameritech.net) +as noted by Will Fitzerald)
  • "Good news." diff --git a/unused/tz-link.htm b/unused/tz-link.htm new file mode 100644 index 000000000000..0cd9e28a3056 --- /dev/null +++ b/unused/tz-link.htm @@ -0,0 +1,648 @@ + + + +Sources for Time Zone and Daylight Saving Time Data + + + + + + + + + + +

    Sources for Time Zone and Daylight Saving Time Data

    +
    +@(#)tz-link.htm 8.18 +
    +

    +Please send corrections to this web page to the +time zone mailing list.

    +

    The tz database

    +

    +The public-domain +time zone database contains code and data +that represent the history of local time +for many representative locations around the globe. +It is updated periodically to reflect changes made by political bodies +to time zone +boundaries, UTC offsets, and +daylight-saving +rules. +This database (often called tz or zoneinfo) +is used by several implementations, +including +the +GNU +C Library used in +GNU/Linux, +FreeBSD, +NetBSD, +OpenBSD, +Cygwin, +DJGPP, +AIX, +Mac OS X, +OpenVMS, +Oracle Database, +Solaris, +Tru64, and +UnixWare.

    +

    +Each location in the database represents a national region where all +clocks keeping local time have agreed since 1970. +Locations are identified by continent or ocean and then by the name of +the location, which is typically the largest city within the region. +For example, America/New_York +represents most of the US eastern time zone; +America/Phoenix represents most of Arizona, which +uses mountain time without daylight saving time (DST); +America/Detroit represents most of Michigan, which uses +eastern time but with different DST rules in 1975; +and other entries represent smaller regions like Starke County, +Indiana, which switched from central to eastern time in 1991 +and switched back in 2006. +To use the database on an extended POSIX +implementation set the TZ environment variable to +the location's full name, e.g., TZ="America/New_York".

    +

    +In the tz database's +FTP distribution +the code is in the file tzcodeC.tar.gz, +where C is the code's version; +similarly, the data are in tzdataD.tar.gz, +where D is the data's version. +The following shell commands download +these files to a GNU/Linux or similar host; +see the downloaded +README file for what to do next.

    +
    wget 'ftp://elsie.nci.nih.gov/pub/tz*.tar.gz'
    +gzip -dc tzcode*.tar.gz | tar -xf -
    +gzip -dc tzdata*.tar.gz | tar -xf -
    +
    +

    +The code lets you compile the tz source files into +machine-readable binary files, one for each location. It also lets +you read a tz binary file and interpret time stamps for that +location.

    +

    +The data are by no means authoritative. If you find errors, please +send changes to the time zone +mailing list. You can also browse recent +messages sent to the mailing list, subscribe to it, +retrieve the full archive of old +messages (in gzip compressed format), or retrieve archived older versions of code +and data; there is also a smaller HTTP +mirror.

    +

    +The Web has several other sources for time zone and daylight saving time data. +Here are some recent links that may be of interest. +

    +

    Web pages using recent versions of the tz database

    +

    +These are listed roughly in ascending order of complexity and fanciness. +

    + +

    Other time zone database formats

    + +

    Other tz compilers

    + +

    Other tz binary file readers

    +
      +
    • The GNU C +Library +has an independent, thread-safe implementation of +a tz binary file reader. +This library is freely available under the + +GNU Lesser General Public License +(LGPL), +and is widely used in GNU/Linux systems.
    • +
    • ZoneInfo.java +is a tz binary file reader written in Java. +It is freely available under the LGPL.
    • +
    • Tcl, mentioned above, also contains a +tz binary file reader.
    • +
    +

    Other tz-based time zone software

    +
      +
    • FoxClocks +is an extension for Mozilla +Toolkit applications like Firefox, Thunderbird, and +Sunbird. +It displays multiple clocks in the application window, and has a mapping +interface to Google Earth. +It is freely available under the GPL.
    • +
    • International +clock (intclock) is a multi-timezone clock for +GNU/Linux and similar systems. It is freely available +under the GPL.
    • +
    • PublicDomain +has a copy of a recent tz database, accessed via a C# library. As its +name suggests, it is in the public domain. Only current time stamps +are well supported; historical data are compiled into the runtime but +are not easily accessible.
    • +
    • Sun Java releases since 1.4 +contain a copy of a subset of a recent tz database in a +Java-specific format.
    • +
    • Time Zone is +a WordPress plugin. It is freely +available under a BSD-style license.
    • +
    • VelaTerra is +a Mac OS X program. Its developers +offer free +licenses to tz contributors.
    • +
    • World Time Explorer is a +Microsoft Windows program.
    • +
    +

    Other time zone databases

    + +

    Maps

    + +

    Time zone boundaries

    + +

    Civil time concepts and history

    + +

    National histories of legal time

    +
    +
    Australia
    +
    The Parliamentary Library has commissioned research +note on daylight saving time in Australia. +The Bureau of Meteorology publishes a list of +Implementation Dates of Daylight Savings Time within Australia.
    +
    Belgium
    +
    The Royal Observatory of Belgium maintains a table of time in Belgium (in Dutch).
    +
    Brazil
    +
    The Time Service Department of the National Observatory +records Brazil's daylight saving time decrees (in +Portuguese).
    +
    Canada
    +
    The Institute for National Measurement Standards publishes current +and some older information about Time +Zones & Daylight Saving Time.
    +
    Chile
    +
    The Chilean Hydrographic and Oceanographic Service publishes a history of +official time (in Spanish).
    +
    Germany
    +
    The National Institute for Science and Technology maintains the Realisation of +Legal Time in Germany.
    +
    Israel
    +
    The Interior Ministry periodically issues announcements (in Hebrew).
    +
    Mexico
    +
    The Investigation and Analysis Service of the Mexican Library of +Congress has published a history of Mexican local time (in Spanish).
    +
    Malaysia
    +
    See Singapore below.
    +
    Netherlands
    +
    Legal time in the Netherlands (in Dutch) +covers the history of local time in the Netherlands from ancient times.
    +
    New Zealand
    +
    The Department of Internal Affairs maintains a brief history About +Daylight Saving. The privately-maintained History of New Zealand +time has more details.
    +
    Norway
    +
    The Norwegian Meteorological Institute lists +Summer +time in Norway (in Norwegian), citing the +Institute of Theoretical Astrophysics, Oslo.
    +
    Singapore
    +
    Why +is Singapore in the "Wrong" Time Zone? details the +history of legal time in Singapore and Malaysia.
    +
    United Kingdom
    +
    History of +legal time in Britain discusses in detail the country +with perhaps the best-documented history of clock adjustments. +The National Physical Laboratory also maintains an Archive +of Summer time dates.
    +
    +

    Precision timekeeping

    + +

    Time notation

    +
      +
    • +A Summary of +the International Standard Date and Time Notation is a good +summary of +ISO +8601:2004 -- Data elements and interchange formats -- Information +interchange -- Representation of dates and times.
    • +
    • +XML +Schema: Datatypes - dateTime specifies a format inspired by +ISO 8601 that is in common use in XML data.
    • +
    • +Internet +Message Format (Internet RFC 2822) §3.3 +specifies the time notation used in email and HTTP +headers.
    • +
    • +Date and Time +on the Internet: Timestamps (Internet RFC 3339) +specifies an ISO 8601 +profile for use in new Internet +protocols.
    • +
    • +Date & Time +Formats on the Web surveys web- and Internet-oriented date and time +formats.
    • +
    • +The +Best of Dates, the Worst of Dates covers many problems encountered +by software developers when handling dates and time stamps.
    • +
    • The Unicode Common Locale Data Repository +(CLDR) Project has localizations for time zone names, +abbreviations, identifiers, and formats. For example, it contains +French translations for "Eastern European Summer Time", "EEST", and +"Bucharest". By-Type +Chart: names.metazone shows these values for many locales. +ICU contains a mechanism for using this data.
    • +
    • Alphabetic time zone abbreviations should not be used as unique +identifiers for UTC offsets as they are ambiguous in +practice. For example, "EST" denotes 5 hours behind +UTC in English-speaking North America, but it denotes 10 +or 11 hours ahead of UTC in Australia; and +French-speaking North Americans prefer +"HNE" to +"EST". For POSIX the tz +database contains English abbreviations for all time stamps but in +many cases these are merely inventions of the database +maintainers.
    • +
    • Numeric time zone abbreviations typically count hours east of +UTC, e.g., +09 for Japan and +-10 for Hawaii. However, the POSIX +TZ environment variable uses the opposite convention. For +example, one might use TZ="JST-9" and +TZ="HST10" for Japan and Hawaii, respectively. If the +tz database is available, it is usually better to use +settings like TZ="Asia/Tokyo" and +TZ="Pacific/Honolulu" instead, as this should avoid +confusion, handle old time stamps better, and insulate you better from +any future changes to the rules. One should never set +POSIX TZ to a value like +"GMT-9", though, since this would falsely claim that +local time is nine hours ahead of UTC and the time zone +is called "GMT".
    • +
    +

    Related indexes

    + + + diff --git a/unused/tzfile.5.txt b/unused/tzfile.5.txt new file mode 100644 index 000000000000..953851233d6c --- /dev/null +++ b/unused/tzfile.5.txt @@ -0,0 +1,106 @@ +NAME + + tzfile - time zone information + +SYNOPSIS + #include + +DESCRIPTION + The time zone information files used by tzset(3) begin with + the magic characters "TZif" to identify then as time zone + information files, followed by a character identifying the + version of the file's format (as of 2005, either an ASCII + NUL or a '2') followed by fifteen bytes containing zeroes + reserved for future use, followed by six four-byte values of + type long, written in a ``standard'' byte order (the high- + order byte of the value is written first). These values + are, in order: + + tzh_ttisgmtcnt + The number of UTC/local indicators stored in the file. + + tzh_ttisstdcnt + The number of standard/wall indicators stored in the + file. + + tzh_leapcnt + The number of leap seconds for which data is stored in + the file. + + tzh_timecnt + The number of "transition times" for which data is + stored in the file. + + tzh_typecnt + The number of "local time types" for which data is + stored in the file (must not be zero). + + tzh_charcnt + The number of characters of "time zone abbreviation + strings" stored in the file. + + The above header is followed by tzh_timecnt four-byte values + of type long, sorted in ascending order. These values are + written in ``standard'' byte order. Each is used as a + transition time (as returned by time(2)) at which the rules + for computing local time change. Next come tzh_timecnt one- + byte values of type unsigned char; each one tells which of + the different types of ``local time'' types described in the + file is associated with the same-indexed transition time. + These values serve as indices into an array of ttinfo + structures (with tzh_typecnt entries) that appears next in + the file; these structures are defined as follows: + + struct ttinfo { + long tt_gmtoff; + int tt_isdst; + unsigned int tt_abbrind; + }; + + Each structure is written as a four-byte value for tt_gmtoff + of type long, in a standard byte order, followed by a one- + byte value for tt_isdst and a one-byte value for tt_abbrind. + In each structure, tt_gmtoff gives the number of seconds to + be added to UTC, tt_isdst tells whether tm_isdst should be + set by localtime (3) and tt_abbrind serves as an index into + the array of time zone abbreviation characters that follow + the ttinfo structure(s) in the file. + + Then there are tzh_leapcnt pairs of four-byte values, + written in standard byte order; the first value of each pair + gives the time (as returned by time(2)) at which a leap + second occurs; the second gives the total number of leap + seconds to be applied after the given time. The pairs of + values are sorted in ascending order by time. + + Then there are tzh_ttisstdcnt standard/wall indicators, each + stored as a one-byte value; they tell whether the transition + times associated with local time types were specified as + standard time or wall clock time, and are used when a time + zone file is used in handling POSIX-style time zone + environment variables. + + Finally there are tzh_ttisgmtcnt UTC/local indicators, each + stored as a one-byte value; they tell whether the transition + times associated with local time types were specified as UTC + or local time, and are used when a time zone file is used in + handling POSIX-style time zone environment variables. + + Localtime uses the first standard-time ttinfo structure in + the file (or simply the first ttinfo structure in the + absence of a standard-time structure) if either tzh_timecnt + is zero or the time argument is less than the first + transition time recorded in the file. + + For version-2-format time zone files, the above header and + data is followed by a second header and data, identical in + format except that eight bytes are used for each transition + time or leap second time. After the second header and data + comes a newline-enclosed, POSIX-TZ-environment-variable- + style string for use in handling instants after the last + transition time stored in the file (with nothing between the + newlines if there is no POSIX representation for such + instants). + +SEE ALSO + newctime(3) diff --git a/unused/tzselect.8 b/unused/tzselect.8 new file mode 100644 index 000000000000..949d9f7bf35a --- /dev/null +++ b/unused/tzselect.8 @@ -0,0 +1,41 @@ +.TH TZSELECT 8 +.SH NAME +tzselect \- select a time zone +.SH SYNOPSIS +.B tzselect +.SH DESCRIPTION +The +.B tzselect +program asks the user for information about the current location, +and outputs the resulting time zone description to standard output. +The output is suitable as a value for the TZ environment variable. +.PP +All interaction with the user is done via standard input and standard error. +.SH "ENVIRONMENT VARIABLES" +.TP +\f3AWK\fP +Name of a Posix-compliant +.I awk +program (default: +.BR awk ). +.TP +\f3TZDIR\fP +Name of the directory containing time zone data files (default: +.BR /usr/local/etc/zoneinfo ). +.SH FILES +.TP +\f2TZDIR\fP\f3/iso3166.tab\fP +Table of ISO 3166 2-letter country codes and country names. +.TP +\f2TZDIR\fP\f3/zone.tab\fP +Table of country codes, latitude and longitude, TZ values, and +descriptive comments. +.TP +\f2TZDIR\fP\f3/\fP\f2TZ\fP +Time zone data file for time zone \f2TZ\fP. +.SH "EXIT STATUS" +The exit status is zero if a time zone was successfully obtained from the user, +nonzero otherwise. +.SH "SEE ALSO" +newctime(3), tzfile(5), zdump(8), zic(8) +.\" @(#)tzselect.8 8.1 diff --git a/unused/tzselect.8.txt b/unused/tzselect.8.txt new file mode 100644 index 000000000000..a492401b8219 --- /dev/null +++ b/unused/tzselect.8.txt @@ -0,0 +1,41 @@ +NAME + + tzselect - select a time zone + +SYNOPSIS + tzselect + +DESCRIPTION + The tzselect program asks the user for information about the + current location, and outputs the resulting time zone + description to standard output. The output is suitable as a + value for the TZ environment variable. + + All interaction with the user is done via standard input and + standard error. + +ENVIRONMENT VARIABLES + AWK Name of a Posix-compliant awk program (default: awk). + + TZDIR + Name of the directory containing time zone data files + (default: /usr/local/etc/zoneinfo). + +FILES + TZDIR/iso3166.tab + Table of ISO 3166 2-letter country codes and country + names. + + TZDIR/zone.tab + Table of country codes, latitude and longitude, TZ + values, and descriptive comments. + + TZDIR/TZ + Time zone data file for time zone TZ. + +EXIT STATUS + The exit status is zero if a time zone was successfully + obtained from the user, nonzero otherwise. + +SEE ALSO + newctime(3), tzfile(5), zdump(8), zic(8) diff --git a/unused/tzselect.ksh b/unused/tzselect.ksh new file mode 100644 index 000000000000..7b805336ab5d --- /dev/null +++ b/unused/tzselect.ksh @@ -0,0 +1,323 @@ +#! /bin/ksh + +VERSION='@(#)tzselect.ksh 8.2' + +# Ask the user about the time zone, and output the resulting TZ value to stdout. +# Interact with the user via stderr and stdin. + +# Contributed by Paul Eggert. + +# Porting notes: +# +# This script requires several features of the Korn shell. +# If your host lacks the Korn shell, +# you can use either of the following free programs instead: +# +# +# Bourne-Again shell (bash) +# +# +# +# Public domain ksh +# +# +# This script also uses several features of modern awk programs. +# If your host lacks awk, or has an old awk that does not conform to Posix.2, +# you can use either of the following free programs instead: +# +# +# GNU awk (gawk) +# +# +# +# mawk +# + + +# Specify default values for environment variables if they are unset. +: ${AWK=awk} +: ${TZDIR=$(pwd)} + +# Check for awk Posix compliance. +($AWK -v x=y 'BEGIN { exit 123 }') /dev/null 2>&1 +[ $? = 123 ] || { + echo >&2 "$0: Sorry, your \`$AWK' program is not Posix compatible." + exit 1 +} + +if [ "$1" = "--help" ]; then + cat <&2 "$0: time zone files are not set up correctly" + exit 1 + } +done + +newline=' +' +IFS=$newline + + +# Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout. +case $(echo 1 | (select x in x; do break; done) 2>/dev/null) in +?*) PS3= +esac + + +# Begin the main loop. We come back here if the user wants to retry. +while + + echo >&2 'Please identify a location' \ + 'so that time zone rules can be set correctly.' + + continent= + country= + region= + + + # Ask the user for continent or ocean. + + echo >&2 'Please select a continent or ocean.' + + select continent in \ + Africa \ + Americas \ + Antarctica \ + 'Arctic Ocean' \ + Asia \ + 'Atlantic Ocean' \ + Australia \ + Europe \ + 'Indian Ocean' \ + 'Pacific Ocean' \ + 'none - I want to specify the time zone using the Posix TZ format.' + do + case $continent in + '') + echo >&2 'Please enter a number in range.';; + ?*) + case $continent in + Americas) continent=America;; + *' '*) continent=$(expr "$continent" : '\([^ ]*\)') + esac + break + esac + done + case $continent in + '') + exit 1;; + none) + # Ask the user for a Posix TZ string. Check that it conforms. + while + echo >&2 'Please enter the desired value' \ + 'of the TZ environment variable.' + echo >&2 'For example, GST-10 is a zone named GST' \ + 'that is 10 hours ahead (east) of UTC.' + read TZ + $AWK -v TZ="$TZ" 'BEGIN { + tzname = "[^-+,0-9][^-+,0-9][^-+,0-9]+" + time = "[0-2]?[0-9](:[0-5][0-9](:[0-5][0-9])?)?" + offset = "[-+]?" time + date = "(J?[0-9]+|M[0-9]+\.[0-9]+\.[0-9]+)" + datetime = "," date "(/" time ")?" + tzpattern = "^(:.*|" tzname offset "(" tzname \ + "(" offset ")?(" datetime datetime ")?)?)$" + if (TZ ~ tzpattern) exit 1 + exit 0 + }' + do + echo >&2 "\`$TZ' is not a conforming" \ + 'Posix time zone string.' + done + TZ_for_date=$TZ;; + *) + # Get list of names of countries in the continent or ocean. + countries=$($AWK -F'\t' \ + -v continent="$continent" \ + -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ + ' + /^#/ { next } + $3 ~ ("^" continent "/") { + if (!cc_seen[$1]++) cc_list[++ccs] = $1 + } + END { + while (getline &2 'Please select a country.' + select country in $countries + do + case $country in + '') echo >&2 'Please enter a number in range.';; + ?*) break + esac + done + + case $country in + '') exit 1 + esac;; + *) + country=$countries + esac + + + # Get list of names of time zone rule regions in the country. + regions=$($AWK -F'\t' \ + -v country="$country" \ + -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ + ' + BEGIN { + cc = country + while (getline &2 'Please select one of the following' \ + 'time zone regions.' + select region in $regions + do + case $region in + '') echo >&2 'Please enter a number in range.';; + ?*) break + esac + done + case $region in + '') exit 1 + esac;; + *) + region=$regions + esac + + # Determine TZ from country and region. + TZ=$($AWK -F'\t' \ + -v country="$country" \ + -v region="$region" \ + -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ + ' + BEGIN { + cc = country + while (getline &2 "$0: time zone files are not set up correctly" + exit 1 + } + esac + + + # Use the proposed TZ to output the current date relative to UTC. + # Loop until they agree in seconds. + # Give up after 8 unsuccessful tries. + + extra_info= + for i in 1 2 3 4 5 6 7 8 + do + TZdate=$(LANG=C TZ="$TZ_for_date" date) + UTdate=$(LANG=C TZ=UTC0 date) + TZsec=$(expr "$TZdate" : '.*:\([0-5][0-9]\)') + UTsec=$(expr "$UTdate" : '.*:\([0-5][0-9]\)') + case $TZsec in + $UTsec) + extra_info=" +Local time is now: $TZdate. +Universal Time is now: $UTdate." + break + esac + done + + + # Output TZ info and ask the user to confirm. + + echo >&2 "" + echo >&2 "The following information has been given:" + echo >&2 "" + case $country+$region in + ?*+?*) echo >&2 " $country$newline $region";; + ?*+) echo >&2 " $country";; + +) echo >&2 " TZ='$TZ'" + esac + echo >&2 "" + echo >&2 "Therefore TZ='$TZ' will be used.$extra_info" + echo >&2 "Is the above information OK?" + + ok= + select ok in Yes No + do + case $ok in + '') echo >&2 'Please enter 1 for Yes, or 2 for No.';; + ?*) break + esac + done + case $ok in + '') exit 1;; + Yes) break + esac +do : +done + +case $SHELL in +*csh) file=.login line="setenv TZ '$TZ'";; +*) file=.profile line="TZ='$TZ'; export TZ" +esac + +echo >&2 " +You can make this change permanent for yourself by appending the line + $line +to the file '$file' in your home directory; then log out and log in again. + +Here is that TZ value again, this time on standard output so that you +can use the $0 command in shell scripts:" + +echo "$TZ" diff --git a/unused/usno1988 b/unused/usno1988 new file mode 100644 index 000000000000..5766d9b057b9 --- /dev/null +++ b/unused/usno1988 @@ -0,0 +1,111 @@ +# @(#)usno1988 8.1 +# +# From Arthur David Olson (1989-01-19): +# +# Here's some United States Naval Observatory time zone data from +# February 1988. It's here mostly to convince you that the USNO has indeed +# been updating its files (see its 1989 data elsewhere). +# +ANDORRA 1 H AHEAD OF UTC +ARGENTINA 3 H BEHIND UTC +BRASIL WEST 5 H BEHIND UTC (CRUZEIRO DO SUL) +BRASIL CENTRAL 4 H BEHIND UTC (MANAUS) +BRASIL EAST 3 H BEHIND UTC COASTAL STATES, RIO, SP, BRASILIA +BRASIL 2 H BEHIND UTC ATLANTIC ISLANDS +BRAZIL 5 H BEHIND UTC WEST (CRUZEIRO DO SUL) +BRAZIL 4 H BEHIND UTC CENTRAL (MANAUS) +BRAZIL 3 H BEHIND UTC COASTAL STATES, RIO, SP, BRASILIA +BRAZIL 3 H BEHIND UTC FOR MOST MAJOR AIRPORTS. +BRAZIL 2 H BEHIND UTC ATLANTIC ISLANDS +BULGARIA 2 H AHEAD OF UTC WINTER +BULGARIA 3 H AHEAD OF UTC SUMMER MAR31 - SEP 85, 0100 LOCAL +CHINA 8 H AHEAD OF UTC; ALL OF CHINA, INCL TAIWAN +CUBA 5 H BEHIND UTC IN WINTER +CUBA 4 H BEHIND UTC MAY 8 - OCT 8 +CYPRUS 2 H AHEAD UTC IN WINTER +CYPRUS 3 H AHEAD UTC MAR 25 - SEP 30 +DENMARK 1 H AHEAD UTC IN WINTER +DENMARK 2 H AHEAD UTC MAR 31 - SEP 30 , 0200 LOCAL +DENMK. FAEROE IS 1 H AHEAD UTC MAR 31 - SEP 30 , 0200 LOCAL +EGYPT 2 H AHEAD UTC +EGYPT 3 H AHEAD UTC SUMMER (AFTER RAMADAN) +ENGLAND ON UTC IN WINTER; WALES, SCOTLAND, N.I., CH.IS. +ENGLAND 1 H AHEAD OF UTC; SUMMER TIL 28 OCT 0200 LOCAL +FINLAND 2 H AHEAD OF UTC IN WINTER +FINLAND 3 H AHEAD OF UTC MAR 25 - SEP 30 +FRANCE 1 H AHEAD OF UTC IN WINTER +FRANCE 2 H AHEAD OF UTC MAR 31 - SEP 30 , 0100 LOCAL +GREECE 2 H AHEAD OF UTC IN WINTER +GREECE 3 H AHEAD OF UTC IN SUMMER EFF. 31MAR85 02/03 LOCAL +GREECE 3 H AHEAD OF UTC MAR 25 - SEP 30 +GREENLAND 4 H BEHIND UTC IN THULE AIRBASE YEAR ROUND +GREENLAND 3 H BEHIND UTC IN WINTER AT SONDRESTROM +GREENLAND 2 H BEHIND UTC 30 MAR - 30 SEP 2200 LOCAL AT -"- +GREENLAND 2 H BEHIND UTC AROUND SCORESBY SUND +ICELAND ON UTC +IRAN 3.5H AHEAD OF UTC +IRELAND ON UTC IN WINTER +IRELAND 1 H AHEAD OF UTC MAR 31 - OCT 23 0200 LOCAL +ITALY 1 H AHEAD OF UTC IN WINTER +ITALY 2 H AHEAD OF UTC MAR 31 - SEP 30, 0030 LOCAL +JAMAICA 5 H BEHIND UTC IN WINTER +JAMAICA 4 H BEHIND UTC APR 29 - OCT 29 +LIBYA 2 H AHEAD OF UTC +MEXICO BAJA CAL N 8 H BEHIND UTC IN WINTER; NORTH BAJA CAL, TIJUANA +MEXICO BAJA CAL N 7 H BEHIND UTC APR 29 - OCT 29 +MEXICO BAJA CAL S 7 H BEHIND UTC ALL YEAR; MAZATLAN +MEXICO CENTRAL 6 H BEHIND UTC ALL YEAR; MEXICO CITY +MONACO 1 H AHEAD UTC IN WINTER +MONACO 2 H AHEAD UTC MAR 25 - SEP30 +PARAGUAY 4 H BEHIND UTC IN WINTER +PARAGUAY 3 H BEHIND UTC SEP 30 - MAR 30 +POLAND 1 H AHEAD OF UTC IN WINTER +POLAND 2 H AHEAD OF UTC MAR 24 - SEP 0200 LOCAL +PORTUGAL ON UTC IN WINTER +PORTUGAL 1 H AHEAD OF UTC IN SUMMER MAR 31 - SEP 29 0100 LOCAL +PORTUGAL AZORES 1 H BEHIND UTC IN WINTER +PORTUGAL AZORES ON UTC IN SUMMER MAR 31 - SEP 29 +PORTUGAL MADEIRA ON UTC ALL YEAR; +ROMANIA 2 H AHEAD OF UTC IN WINTER +ROMANIA 3 H AHEAD OF UTC APR 3 - SEP 24 +SCOTLAND SEE ENGLAND +SWITZERLAND 1 H AHEAD OF UTC IN WINTER +SWITZERLAND 2 H AHEAD OF UTC MAR 31 - SEP 30 0200 LOCAL +TURKEY 3 H AHEAD OF UTC +USA EASTERN 5 H BEHIND UTC IN WINTER; NEW YORK, WASHINGTON +USA EASTERN 4 H BEHIND UTC APR 29 - OCT 29 +USA CENTRAL 6 H BEHIND UTC IN WINTER; CHICAGO, HOUSTON +USA CENTRAL 5 H BEHIND UTC APR 29 - OCT 29 +USA MOUNTAIN 7 H BEHIND UTC IN WINTER; DENVER +USA MOUNTAIN 6 H BEHIND UTC APR 29 - OCT 29 +USA PACIFIC 8 H BEHIND UTC IN WINTER; L.A., SAN FRANCISCO +USA PACIFIC 7 H BEHIND UTC APR 29 - OCT 29 +USA ALASKA STD 9 H BEHIND UTC IN WINTER; MOST OF ALASKA (AKST) +USA ALASKA STD 8 H BEHIND UTC APR 29 - OCT 29 (AKDT) +USA ALEUTIAN 10 H BEHIND UTC IN WINTER; ISLANDS WEST OF 170W +USA - " - 9 H BEHIND UTC APR 29 - OCT 29 +USA HAWAII 10 H BEHIND UTC ALL YEAR; +USA BERING 11 H BEHIND UTC ALL YEAR; SAMOA, MIDWAY +USSR WEST EUROP 3 H AHEAD OF UTC IN WINTER; LENINGRAD, MOSCOW +USSR WEST EUROP 4 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL EUR 4 H AHEAD OF UTC IN WINTER; ROSTOV, BAKU +USSR CENTRAL EUR 5 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST EUROP 5 H AHEAD OF UTC IN WINTER; SVERDLOVSK +USSR EAST EUROP 6 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST SIBERIAN 6 H AHEAD OF UTC IN WINTER; TASHKENT, ALMA ATA +USSR WEST SIBERIAN 7 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 7 H AHEAD OF UTC IN WINTER; NOVOSIBIRSK +USSR WEST-CENTRAL 8 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 8 H AHEAD OF UTC IN WINTER; IRKUTSK +USSR WEST-CENTRAL 9 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 9 H AHEAD OF UTC IN WINTER; YAKUTSK +USSR CENTRAL SIB 10 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 10 H AHEAD OF UTC IN WINTER; VLADIVOSTOK +USSR CENTRAL SIB 11 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 11 H AHEAD OF UTC IN WINTER; MAGADAN +USSR EAST SIBERIA 12 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 12 H AHEAD OF UTC IN WINTER; PETROPAVLOVSK +USSR EAST SIBERIA 13 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 13 H AHEAD OF UTC IN WINTER; UELEN +USSR EAST SIBERIA 14 H AHEAD OF UTC APR 1 - SEP 30 +WALES SEE ENGLAND diff --git a/unused/usno1989 b/unused/usno1989 new file mode 100644 index 000000000000..e242cb90d374 --- /dev/null +++ b/unused/usno1989 @@ -0,0 +1,452 @@ +# @(#)usno1989 8.1 +# +# From Arthur David Olson (1989-01-19): +# +# Here's time zone information from the United States Naval Observatory; +# no corrections have been made, and there are some obvious challenges. +# The USNO warns: +# DUE TO FREQUENT CHANGES IN THE LOCAL LAWS GOVERNING DAYLIGHT +# SAVING TIME, WE CANNOT GUARANTEE THE ACCURACY OF THIS +# INFORMATION. PLEASE ALERT US TO ANY DISCREPANCY YOU MAY +# DISCOVER. +# +AFGHANISTAN 4.5H AHEAD OF UTC +ALBANIA 1 H AHEAD OF UTC +ALBANIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ALBANIA (ESTIMATED) +ALGERIA 1 H AHEAD OF UTC +AMERICAN SAMOA 11 H BEHIND UTC +ANDORRA 1 H AHEAD OF UTC +ANDORRA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ANDORRA (ESTIMATED) +ANGOLA 1 H AHEAD OF UTC +ARGENTINA 3 H BEHIND UTC +ARUBA 4 H BEHIND UTC ALSO BONAIRE, CURACAO, +ARUBA ST.MAARTEN +AUSTRALIA WEST 8 H AHEAD OF UTC PERTH, EXMOUTH +AUSTRALIA N.T. 9.5H AHEAD OF UTC DARWIN NO ADVANCED TIME +AUSTRALIA N.T. IN SUMMER +AUSTRALIA SOUTH 9.5H AHEAD OF UTC ADELAIDE +AUSTRALIA INCLUDING BROKEN HILL, NSW +AUSTRALIA SOUTH 10.5H AHEAD OF UTC ADELAIDE OCT 30, '88-MAR +AUSTRALIA SOUTH 18, '89 INCLUDING BROKEN +AUSTRIALIA SOUTH HILL, NSW +AUSTRALIA QUEENL 10 H AHEAD OF UTC +AUSTRALIA NSW 10 H AHEAD OF UTC SYDNEY +AUSTRALIA NSW 11 H AHEAD OF UTC SYDNEY OCT 30, '88-MAR 18, +AUSTRALIA NSW '89 +AUSTRALIA TASM. 10 H AHEAD OF UTC HOBART +AUSTRALIA TASM. 11 H AHEAD OF UTC HOBART OCT 30, '88-MAR 18, +AUSTRALIA TASM. '89 +AUSTRIA 1 H AHEAD OF UTC +AUSTRIA 2 H AHEAD OF UTC MAR 27 - SEPT 24 +AZORES SEE PORTUGAL +BAHAMAS 5 H BEHIND UTC EXCLUDING TURKS AND CAICOS +BAHAMAS ISLANDS) +BAHAMAS 4 H BEHIND UTC APR 3 - OCT 29 (SAME +BAHAMAS EXCLUSION) +BAHRAIN 3 H AHEAD OF UTC +BANGLADESH 6 H AHEAD OF UTC +BARBADOS 4 H BEHIND UTC +BELGIUM 1 H AHEAD OF UTC +BELGIUM 2 H AHEAD OF UTC MAR 27 - SEP 24 +BELIZE 6 H BEHIND UTC +BENIN PEOPLES REP 1 H AHEAD OF UTC DAHOMEY +BERMUDA 4 H BEHIND UTC +BERMUDA 3 H BEHIND UTC APR 3 - OCT 29 +BHUTAN 6 H AHEAD OF UTC +BOLIVIA 4 H BEHIND UTC +BONAIRE 4 H BEHIND UTC ALSO ARUBA,CURACAO, +BONAIRE ST.MAARTEN, SABA +BOTSWANA 2 H AHEAD OF UTC +BRAZIL WEST 5 H BEHIND UTC TERRITORY OF ACRE +BRAZIL WEST 4 H BEHIND UTC ACRE OCT 23, '88-FEB 11, +BRAZIL '89 (ESTIMATED) +BRAZIL CENTRAL 4 H BEHIND UTC MANAUS +BRAZIL CENTRAL 3 H BEHIND UTC MANAUS OCT 23, '88-FEB 11, +BRAZIL CENTRAL '89 (ESTIMATED) +BRAZIL EAST 3 H BEHIND UTC COASTAL STATES, RIO, SAO +BRAZIL EAST PAULO, BRASILIA +BRAZIL EAST 2 H BEHIND UTC COASTAL STATES, RIO, SAO +BRAZIL PAULO, BRASILIA OCT 23, +BRAZIL '88-FEB 11, '89 +BRAZIL (ESTIMATED) +BRAZIL 2 H BEHIND UTC ATLANTIC ISLANDS, FERNANDO +BRAZIL DE NORONHA +BRAZIL 1 H BEHIND UTC OCT 23, '88-FEB 11, '89 +BRAZIL (ESTIMATED) +BRAZIL 3 H BEHIND UTC FOR MOST MAJOR AIRPORTS. +BRITISH VIRGIN I. 4 H BEHIND UTC +BRUNEI 8 H AHEAD OF UTC +BULGARIA 2 H AHEAD OF UTC +BULGARIA 3 H AHEAD OF UTC MAR 27 - SEP 24 +BURKINA FASO ON UTC +BURMA 6.5H AHEAD OF UTC +BURUNDI 2 H AHEAD OF UTC +CAMBODIA SEE KAMPUCHEA +CAMEROON 1 H AHEAD OF UTC +CANADA NEW FDL 3.5H BEHIND UTC ST.JOHN'S +CANADA NEW FDL 1.5H BEHIND UTC APR 3 - OCT 29 +CANADA ATLANTIC 4 H BEHIND UTC HALIFAX +CANADA ATLANTIC 3 H BEHIND UTC APR 3 - OCT 29 +CANADA EASTERN 5 H BEHIND UTC TORONTO, MONTREAL, OTTAWA +CANADA EASTERN 4 H BEHIND UTC APR 3 - OCT 29 +CANADA CENTRAL 6 H BEHIND UTC REGINA, WINNIPEG +CANADA CENTRAL 5 H BEHIND UTC APR 3 - OCT 29 +CANADA MOUNTAIN 7 H BEHIND UTC CALGARY, EDMONTON +CANADA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 29 +CANADA PACIFIC 8 H BEHIND UTC VANCOUVER +CANADA PACIFIC 7 H BEHIND UTC APR 3 - OCT 29 +CANADA YUKON SAME AS PACIFIC DAWSON +CAPE VERDE 1 H BEHIND UTC +CAYMAN ISLANDS 5 H BEHIND UTC +CAROLINE ISLAND 10 H AHEAD OF UTC EXCLUDING PONAPE IS., +CAROLINE ISLAND KUSAIE, AND PINGELAP +CENTRAL AFRICA 1 H AHEAD OF UTC +CEYLON 5.5H AHEAD OF UTC, SEE SRI LANKA +CHAD 1 H AHEAD OF UTC +CHANNEL ISLANDS SEE ENGLAND +CHILE 4 H BEHIND UTC CONTINENTAL +CHILE 3 H BEHIND UTC OCT 9, '88-MAR 11, '89 +CHILE 6 H BEHIND UTC EASTER ISLAND +CHILE 5 H BEHIND UTC OCT 9, '88-MAR 11, '89 +CHINA 8 H AHEAD OF UTC ALL OF CHINA, INCL TAIWAN +CHINA 9 H AHEAD OF UTC APR 17 - SEP 10 +COCOS (Keeling) I. 6.5H AHEAD OF UTC +COLOMBIA 5 H BEHIND UTC +COMOROS 3 H AHEAD OF UTC +CONGO 1 H AHEAD OF UTC +COOK ISLANDS 10 H BEHIND UTC +COOK ISLANDS 9.5H BEHIND UTC OCT 30, '88-MAR 24, '89 +COOK ISLANDS (ESTIMATED) +COSTA RICA 6 H BEHIND UTC +COTE D'IVOIRE ON UTC +CUBA 5 H BEHIND UTC +CUBA 4 H BEHIND UTC MAR 20 - OCT 8 +CURACAO 4 H BEHIND UTC ALSO BONAIRE, ARUBA, +CURACAO ST.MAARTEN +CYPRUS 2 H AHEAD OF UTC +CYPRUS 3 H AHEAD OF UTC MAR 27 - SEP 24 +CZECHOSLOVAKIA 1 H AHEAD OF UTC +CZECHOSLOVAKIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +DENMARK 1 H AHEAD OF UTC +DENMARK 2 H AHEAD OF UTC MAR 27 - SEP 24 +DENMK. FAEROE IS 1 H AHEAD OF UTC MAR 27 - SEP 24 +DJIBOUTI 3 H AHEAD OF UTC +DOMINICA 4 H BEHIND UTC +DOMINICAN REP 4 H BEHIND UTC +ECUADOR 5 H BEHIND UTC CONTINENTAL +ECUADOR 6 H BEHIND UTC GALAPAGOS ISLANDS +EGYPT 2 H AHEAD OF UTC +EGYPT 3 H AHEAD OF UTC MAY 17 - SEP 30 (AFTER +EGYPT RAMADAN) +EL SALVADOR 6 H BEHIND UTC +ENGLAND ON UTC (WALES, SCOTLAND, N.I., +ENGLAND CH. IS.) +ENGLAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +ENEZUELA 4 H BEHIND UTC +EQUITORIAL GUINEA 1 H AHEAD OF UTC +ETHIOPIA 3 H AHEAD OF UTC +FALKLAND ISLANDS 4 H BEHIND UTC +FALKLAND ISLANDS 3 H BEHIND UTC SEP 11, '88-APR 15, '89 +FALKLAND ISLANDS (ESTIMATED) +FAROE ISLAND ON UTC +FAROE ISLAND 1 H AHEAD OF UTC MAR 27 - SEP 24 +FIJI 12 H AHEAD OF UTC +FINLAND 2 H AHEAD OF UTC +FINLAND 3 H AHEAD OF UTC MAR 27 - SEP 24 +FRANCE 1 H AHEAD OF UTC +FRANCE 2 H AHEAD OF UTC MAR 27 - SEP 24 +FRENCH GUIANA 3 H BEHIND UTC +FRENCH POLYNESIA 9 H BEHIND UTC GAMBIER ISLAND +FRENCH POLYNESIA 9.5H BEHIND UTC MARQUESAS ISLANDS +FRENCH POLYNESIA 10 H BEHIND UTC SOCIETY ISLANDS, TUBUAI +FRENCH POLYNESIA ISLANDS, TUAMOTU ISLAND, +FRENCH POLYNESIA TAHITI +GABON 1 H AHEAD OF UTC +GAMBIA ON UTC +GERMANY ALL 1 H AHEAD OF UTC +GERMANY ALL 2 H AHEAD OF UTC MAR 27 - SEP 24 +GHANA ON UTC +GIBRALTAR 1 H AHEAD OF UTC +GIBRALTAR 2 H AHEAD OF UTC MAR 27 - SEP 24 +GREECE 2 H AHEAD OF UTC +GREECE 3 H AHEAD OF UTC MAR 27 - SEP 24 +GREENLAND 4 H BEHIND UTC THULE AIRBASE YEAR ROUND +GREENLAND 3 H BEHIND UTC ANGMAGSSALIK AND W. COAST +GREENLAND 2 H BEHIND UTC MAR 27 - SEP 24 +GREENLAND 1 H BEHIND UTC SCORESBYSUND +GREENLAND ON UTC MAR 27 - SEP 24 +GRENADA 4 H BEHIND UTC +GUADELOUPE 4 H BEHIND UTC ST. BARTHELEMY, NORTHERN +GUADELOUPE ST. MARTIN MARTINIQUE +GUAM 10 H AHEAD OF UTC +GUATEMALA 6 H BEHIND UTC +GUINEA ON UTC +GUINEA BISSAU ON UTC +GUINEA REPUBLIC ON UTC +GUINEA EQUATORIAL 1 H AHEAD OF UTC +GUYANA 3 H BEHIND UTC +HAITI 5 H BEHIND UTC +HAITI 4 H BEHIND UTC APR 3 - OCT 29 +HOLLAND SEE NETHERLANDS +HONDURAS 6 H BEHIND UTC +HONG KONG 8 H AHEAD OF UTC +HUNGARY 1 H AHEAD OF UTC +HUNGARY 2 H AHEAD OF UTC MAR 27 - SEP 24 +ICELAND ON UTC +INDIA 5.5H AHEAD OF UTC INCLUDING ANDAMAN ISLANDS +INDONESIA WEST 7 H AHEAD OF UTC SUMATRA, JAVA, BALI, +INDONESIA WEST JAKARTA +INDONESIA CENTRAL 8 H AHEAD OF UTC KALIMANTAN, SULAWESI +INDONESIA EAST 9 H AHEAD OF UTC IRIAN, BARAT +IRAN 3.5H AHEAD OF UTC +IRAQ 3 H AHEAD OF UTC +IRAQ 4 H AHEAD OF UTC APR 1 - SEP 30 +IRELAND ON UTC +IRELAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +ISRAEL 2 H AHEAD OF UTC +ISRAEL 3 H AHEAD OF UTC APR 10 - SEP 3 +ITALY 1 H AHEAD OF UTC +ITALY 2 H AHEAD OF UTC MAR 27 - SEP 24 +IVORY COAST ON UTC +IWAN 8 H AHEAD OF UTC +JAMAICA 5 H BEHIND UTC +JAPAN 9 H AHEAD OF UTC +JOHNSTON ISLAND 10 H BEHIND UTC +JORDAN 2 H AHEAD OF UTC +JORDAN 3 H AHEAD OF UTC APR 1 - OCT 6 +KAMPUCHEA 7 H AHEAD OF UTC +KENYA 3 H AHEAD OF UTC +KIRIBATI, REP OF 12 H AHEAD OF UTC CANTON, ENDERBURY ISLANDS +KIRIBATI, REP OF 11 H AHEAD OF UTC CHRISTMAS ISLAND +KOREA 9 H AHEAD OF UTC +KOREA, REP OF 9 H AHEAD OF UTC +KOREA, REP OF 10 H AHEAD OF UTC MAY 8 - OCT 8 +KUWAIT 3 H AHEAD OF UTC +KUSAIE, PINGELAP 12 H AHEAD OF UTC INCLUDING MARSHALL IS., +KUSAIE, PINGELAP EXCLUDING KWAJALEIN) +KWAJALEIN 12 H BEHIND UTC +LAOS 7 H AHEAD OF UTC +LEBANON 2 H AHEAD OF UTC +LEBANON 3 H AHEAD OF UTC JUN 1 - OCT 31 +LEEWARD ISLANDS 4 H BEHIND UTC ANTIGUA, DOMINICA, +LEEWARD ISLANDS MONTSERRAT, ST. +LEEWARD ISLAANDS CHRISTOPHER, ST. KITTS, +LEEWARD ISLANDS NEVIS, ANGUILLA +LESOTHO 2 H AHEAD OF UTC +LIBERIA ON UTC +LIBYAN ARAB 1 H AHEAD OF UTC JAMAHIRIYA/LIBYA +LIBYAN ARAB 2 H AHEAD OF UTC APR 1 - SEP 30 JAMAHIRIYA/LIBYA +LIECHTENSTEIN 1 H AHEAD OF UTC +LIECHTENSTEIN 2 H AHEAD OF UTC MAR 27 - SEP 24 +LUXEMBOURG 1 H AHEAD OF UTC +LUXEMBOURG 2 H AHEAD OF UTC MAR 27 - SEP 24 +MACAO 8 H AHEAD OF UTC +MADAGASCAR 3 H AHEAD OF UTC +MADEIRA SEE PORTUGAL +MALAWI 2 H AHEAD OF UTC +MALAYSIA 8 H AHEAD OF UTC +MALDIVES 5 H AHEAD OF UTC +MALI ON UTC +MALTA 1 H AHEAD OF UTC +MALTA 2 H AHEAD OF UTC MAR 27 - SEP 24 +MARTINIQUE 4 H BEHIND UTC +MAURITANIA ON UTC +MAURITIUS 4 H AHEAD OF UTC +MARIANA ISLAND 10 H AHEAD OF UTC EXCLUDING GUAM +MEXICO BAJA CAL N 7 H BEHIND UTC BAJA CALIFORNIA SUR AND +MEXICO BAJA CAL N N. PACIFIC COAST (STATES +MEXICO BAJA CAL N OF SINALOA AND SONORA) +MEXICO BAJA CAL N 8 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +MEXICO BAJA CAL N - OCT 29 +MEXICO BAJA CAL N 7 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +MEXICO BAJA CAL N - 0CT 29 +MEXICO 6 H BEHIND UTC STATES OF DURANGO, +MEXICO COAHUILA, NUEVO LEON, +MEXICO TAMAULIPAS +MEXICO 5 H BEHIND UTC STATES OF DURANGO, +MEXICO COAHUILA, NUEVO LEON, +MEXICO TAMAULIPAS APR 3 - OCT 29 +MEXICO 6 H BEHIND UTC GENERAL MEXICO, STATES OF +MEXICO CAMPECHE, QUINTANA ROO AND +MEXICO YUCATAN +MIDWAY ISLAND 11 H BEHIND UTC +MONACO 1 H AHEAD OF UTC +MONACO 2 H AHEAD OF UTC MAR 27 - SEP 24 +MONGOLIA 8 H AHEAD OF UTC +MONGOLIA 9 H AHEAD OF UTC MAR 27 - SEP 24 +MONTSERRAT 4 H BEHIND UTC +MOROCCO ON UTC +MOZAMBIQUE 2 H AHEAD OF UTC +NAMIBIA 2 H AHEAD OF UTC +NAURU, REP OF 12 H AHEAD OF UTC +NEPAL 5H45M AHEAD OF UTC +NETHERLANDS 1 H AHEAD OF UTC +NETHERLANDS 2 H AHEAD OF UTC MAR 27 - SEP 24 +NETHERLANDS 4 H BEHIND UTC ANTILLES AND SOUTHERN ST. +NETHERLANDS MAARTEN +NEW CALEDONIA 11 H AHEAD OF UTC +NEW HEBRIDES SEE VANUATU +NEW ZEALAND 12 H AHEAD OF UTC (EXCLUDING CHATHAM ISLAND) +NEW ZEALAND 13 H AHEAD OF UTC OCT 30, '88-MAR 4, '89 +NEW ZEALAND 12H45M AHEAD OF UTC CHATHAM ISLAND +NICARAGUA 6 H BEHIND UTC +NIGER 1 H AHEAD OF UTC +NIGERIA 1 H AHEAD OF UTC +NIUE ISLAND 11 H BEHIND UTC +NORFOLK ISLAND 11H30M AHEAD OF UTC +NORTHERN IRELAND ON UTC WALES, SCOTLAND, N.I., +NORTHERN IRELAND CH.IS. +NORTHERN IRELAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +NORWAY 1 H AHEAD OF UTC +NORWAY 2 H AHEAD OF UTC MAR 27 - SEP 24 +OGO ON UTC +OMAN 4 H AHEAD OF UTC +PACIFIC ISLAND T.T. +PALAU ISLAND 9 H AHEAD OF UTC +PAKISTAN 5 H AHEAD OF UTC +PANAMA 5 H BEHIND UTC +PAPUA NEW GUINEA 10 H AHEAD OF UTC INCLUDING BOUGAINVILLE +PAPUA NEW GUINEA ISLAND +PARAGUAY 4 H BEHIND UTC +PARAGUAY 3 H BEHIND UTC OCT 1, '88-MAR 31, '89 +PERU 5 H BEHIND UTC +PHILIPPINES 8 H AHEAD OF UTC +PONAPE ISLAND 11 H AHEAD OF UTC +POLAND 1 H AHEAD OF UTC +POLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +PORTUGAL MAINLAND ON UTC +PORTUGAL MAINLAND 1 H AHEAD OF UTC MAR 27 - SEP 24 +PORTUGAL AZORES 1 H BEHIND UTC +PORTUGAL AZORES ON UTC MAR 27 - SEP 24 +PORTUGAL MADEIRA ON UTC +PORTUGAL MADEIRA 1 H AHEAD OF UTC MAR 27 - SEP 24 +PUERTO RICO 4 H BEHIND UTC +QATAR 3 H AHEAD OF UTC +ROMANIA 2 H AHEAD OF UTC +ROMANIA 3 H AHEAD OF UTC MAR 27 - SEP 24 +RUSSIA SEE USSR +RWANDA 2 H AHEAD OF UTC +SABA 4 H BEHIND UTC ALSO BONAIRE, CURACAO, +SAMOA 11 H BEHIND UTC +SAN MARINO 1 H AHEAD OF UTC +SAN MARINO 2 H AHEAD OF UTC MAR 27 - SEP 24 +SAN SALVADOR 6 H BEHIND UTC +SAO TOME ISLAND ON UTC AND PRINCIPE ISLAND +SAUDI ARABIA 3 H AHEAD OF UTC +SCOTLAND SEE ENGLAND +SENEGAL ON UTC +SEYCHELLES 4 H AHEAD OF UTC +SIERRA LEONE ON UTC +SINGAPORE 8 H AHEAD OF UTC +SOLOMON ISLANDS 11 H AHEAD OF UTC EXCLUDING BOUGAINVILLE +SOLOMON ISLANDS ISLAND +SOMALI 3 H AHEAD OF UTC +SOUTH AFRICA 2 H AHEAD OF UTC +SPAIN CANARY IS ON UTC +SPAIN CANARY IS 1 H AHEAD OF UTC MAR 27 - SEP 24 +SPAIN 1 H AHEAD OF UTC CONTINENTAL, BALEARIC AND +SPAIN MALLORCA ISLANDS +SPAIN 2 H AHEAD OF UTC CONTINENTAL, BALEARIC AND +SPAIN MALLORCA ISLANDS MAR 27 - +SPAIN SEP 24 +SPAIN MAINLAND 1 H AHEAD OF UTC MELILLA +SPAIN MAINLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +SRI LANKA 5H30M AHEAD OF UTC +ST.MAARTEN +ST.KITTS-NEVIS 4 H BEHIND UTC +ST.LUCIA 4 H BEHIND UTC +ST.PIERRE 3 H BEHIND UTC INCLUDING MIQUELON +ST.PIERRE 2 H BEHIND UTC INLCUDING MIQUELON APR 3 +ST.PIERRE - OCT 29 +ST.VINCENT 4 H BEHIND UTC INCLUDING THE GRENADINES +ST. HELENA ON UTC +SURINAME 3 H BEHIND UTC +SWAZILAND 2 H AHEAD OF UTC +SWEDEN 1 H AHEAD OF UTC +SWEDEN 2 H AHEAD OF UTC MAR 27 - SEP 24 +SWITZERLAND 1 H AHEAD OF UTC +SWITZERLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +SYRIA 2 H AHEAD OF UTC +SYRIA 3 H AHEAD OF UTC MAR 15 - OCT 30 +TAHITI 10 H BEHIND UTC +TANZANIA 3 H AHEAD OF UTC +THAILAND 7 H AHEAD OF UTC +TRINIDAD / TOBAGO 4 H BEHIND UTC +TUNISIA 1 H AHEAD OF UTC +TUNISIA 2 H AHEAD OF UTC APR 10 - SEP 24 +TURKEY 2 H AHEAD OF UTC +TURKEY 3 H AHEAD OF UTC MAR 27 - SEP 24 +TURKS AND CAICOS 5 H BEHIND UTC +TURKS AND CAICOS 4 H BEHIND UTC APR 3 - OCT 29 +TUVALU 12 H AHEAD OF UTC +UDAN 2 H AHEAD OF UTC +UGANDA 3 H AHEAD OF UTC +UNITED ARAB EMIR. 4 H AHEAD OF UTC ABU DHABI, DUBAI, SHARJAH, +UNITED ARAB EMIR RAS AL KHAIMAH +UNITED KINGDOM ON UTC WALES, SCOTLAND, N.I., CH. +UNITED KINGDOM IS. +UNITED KINGDOM 1 H AHEAD OF UTC MAR 27 - OCT 22 +UNITED STATES SEE USA +UPPER VOLTA ON UTC +URUGUAY 3 H BEHIND UTC +URUGUAY 2 H BEHIND UTC DEC 11, '88-FEB 25, '89 +URAGUAY (ESTIMATED) +USA EASTERN 5 H BEHIND UTC NEW YORK, WASHINGTON +USA EASTERN 4 H BEHIND UTC APR 3 - OCT 30 +USA CENTRAL 6 H BEHIND UTC CHICAGO, HOUSTON +USA CENTRAL 5 H BEHIND UTC APR 3 - OCT 30 +USA MOUNTAIN 7 H BEHIND UTC DENVER +USA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 30 +USA PACIFIC 8 H BEHIND UTC L.A., SAN FRANCISCO +USA PACIFIC 7 H BEHIND UTC APR 3 - OCT 30 +USA ALASKA STD 9 H BEHIND UTC MOST OF ALASKA (AKST) +USA ALASKA STD 8 H BEHIND UTC APR 3 - OCT 30 (AKDT) +USA ALEUTIAN 10 H BEHIND UTC ISLANDS WEST OF 170W +USA - " - 9 H BEHIND UTC APR 3 - OCT 30 +USA HAWAII 10 H BEHIND UTC +USA BERING 11 H BEHIND UTC SAMOA, MIDWAY +USA FOR SPECIFIC INFO ON USA ZONES/TIMES CALL DOT 202-426-4520 +USSR WEST EUROP 3 H AHEAD OF UTC LENINGRAD, MOSCOW +USSR WEST EUROP 4 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL EUR 4 H AHEAD OF UTC ROSTOV, BAKU +USSR CENTRAL EUR 5 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST EUROP 5 H AHEAD OF UTC SVERDLOVSK +USSR EAST EUROP 6 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST SIBERIAN 6 H AHEAD OF UTC TASHKENT, ALMA ATA +USSR WEST SIBERIAN 7 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 7 H AHEAD OF UTC NOVOSIBIRSK +USSR WEST-CENTRAL 8 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 8 H AHEAD OF UTC IRKUTSK +USSR WEST-CENTRAL 9 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 9 H AHEAD OF UTC YAKUTSK +USSR CENTRAL SIB 10 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 10 H AHEAD OF UTC VLADIVOSTOK +USSR CENTRAL SIB 11 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 11 H AHEAD OF UTC MAGADAN +USSR EAST SIBERIA 12 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 12 H AHEAD OF UTC PETROPAVLOVSK +USSR EAST SIBERIA 13 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 13 H AHEAD OF UTC UELEN +USSR EAST SIBERIA 14 H AHEAD OF UTC APR 1 - SEP 30 +VANUATU 11 H AHEAD OF UTC (NEW HEBRIDES) +VANUATU 12 H AHEAD OF UTC SEP 25, '88-MAR 25, '89 +VANUATU (ESTIMATED) +VATICAN 1 H AHEAD OF UTC +VATICAN 2 H AHEAD OF UTC MAR 27 - SEP 24 +VIETNAM 7 H AHEAD OF UTC +VIRGIN ISLANDS 4 H BEHIND UTC ST.CROIX, ST.THOMAS, +VIRGIN ISLANDS ST.JOHN +WAKE ISLAND 12 H AHEAD OF UTC +WALES SEE ENGLAND +WALLIS/FUTUNA IS. 12 H AHEAD OF UTC +WINDWARD ISLANDS 4 H BEHIND UTC GRENADA, ST. LUCIA +YEMEN 3 H AHEAD OF UTC BOTH REPUBLICS +YUGOSLAVIA 1 H AHEAD OF UTC +YUGOSLAVIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ZAIRE EAST 1 H AHEAD OF UTC KINSHASA MBANDAKA +ZAIRE WEST 2 H AHEAD OF UTC LUBUMBASHI, KASAI, KIVU, +ZAIRE WEST HAUT-ZAIRE, SHABA +ZAMBIA 2 H AHEAD OF UTC +ZIMBABWE 2 H AHEAD OF UTC diff --git a/unused/usno1989a b/unused/usno1989a new file mode 100644 index 000000000000..b197b85bb1d1 --- /dev/null +++ b/unused/usno1989a @@ -0,0 +1,452 @@ +# @(#)usno1989a 8.1 +# +# From Arthur David Olson (1994-02-07): +# +# Here's time zone information from the United States Naval Observatory, +# with corrections from Paul Eggert. +# The USNO warns: +# DUE TO FREQUENT CHANGES IN THE LOCAL LAWS GOVERNING DAYLIGHT +# SAVING TIME, WE CANNOT GUARANTEE THE ACCURACY OF THIS +# INFORMATION. PLEASE ALERT US TO ANY DISCREPANCY YOU MAY +# DISCOVER. +# +AFGHANISTAN 4.5H AHEAD OF UTC +ALBANIA 1 H AHEAD OF UTC +ALBANIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ALBANIA (ESTIMATED) +ALGERIA 1 H AHEAD OF UTC +AMERICAN SAMOA 11 H BEHIND UTC +ANDORRA 1 H AHEAD OF UTC +ANDORRA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ANDORRA (ESTIMATED) +ANGOLA 1 H AHEAD OF UTC +ARGENTINA 3 H BEHIND UTC +ARUBA 4 H BEHIND UTC ALSO BONAIRE, CURACAO, +ARUBA ST.MAARTEN +AUSTRALIA WEST 8 H AHEAD OF UTC PERTH, EXMOUTH +AUSTRALIA N.T. 9.5H AHEAD OF UTC DARWIN NO ADVANCED TIME +AUSTRALIA N.T. IN SUMMER +AUSTRALIA SOUTH 9.5H AHEAD OF UTC ADELAIDE +AUSTRALIA INCLUDING BROKEN HILL, NSW +AUSTRALIA SOUTH 10.5H AHEAD OF UTC ADELAIDE OCT 30, '88-MAR +AUSTRALIA SOUTH 18, '89 INCLUDING BROKEN +AUSTRIALIA SOUTH HILL, NSW +AUSTRALIA QUEENL 10 H AHEAD OF UTC +AUSTRALIA NSW 10 H AHEAD OF UTC SYDNEY +AUSTRALIA NSW 11 H AHEAD OF UTC SYDNEY OCT 30, '88-MAR 18, +AUSTRALIA NSW '89 +AUSTRALIA TASM. 10 H AHEAD OF UTC HOBART +AUSTRALIA TASM. 11 H AHEAD OF UTC HOBART OCT 30, '88-MAR 18, +AUSTRALIA TASM. '89 +AUSTRIA 1 H AHEAD OF UTC +AUSTRIA 2 H AHEAD OF UTC MAR 27 - SEPT 24 +AZORES SEE PORTUGAL +BAHAMAS 5 H BEHIND UTC EXCLUDING TURKS AND CAICOS +BAHAMAS ISLANDS) +BAHAMAS 4 H BEHIND UTC APR 3 - OCT 29 (SAME +BAHAMAS EXCLUSION) +BAHRAIN 3 H AHEAD OF UTC +BANGLADESH 6 H AHEAD OF UTC +BARBADOS 4 H BEHIND UTC +BELGIUM 1 H AHEAD OF UTC +BELGIUM 2 H AHEAD OF UTC MAR 27 - SEP 24 +BELIZE 6 H BEHIND UTC +BENIN PEOPLES REP 1 H AHEAD OF UTC DAHOMEY +BERMUDA 4 H BEHIND UTC +BERMUDA 3 H BEHIND UTC APR 3 - OCT 29 +BHUTAN 6 H AHEAD OF UTC +BOLIVIA 4 H BEHIND UTC +BONAIRE 4 H BEHIND UTC ALSO ARUBA,CURACAO, +BONAIRE ST.MAARTEN, SABA +BOTSWANA 2 H AHEAD OF UTC +BRAZIL WEST 5 H BEHIND UTC TERRITORY OF ACRE +BRAZIL WEST 4 H BEHIND UTC ACRE OCT 23, '88-FEB 11, +BRAZIL '89 (ESTIMATED) +BRAZIL CENTRAL 4 H BEHIND UTC MANAUS +BRAZIL CENTRAL 3 H BEHIND UTC MANAUS OCT 23, '88-FEB 11, +BRAZIL CENTRAL '89 (ESTIMATED) +BRAZIL EAST 3 H BEHIND UTC COASTAL STATES, RIO, SAO +BRAZIL EAST PAULO, BRASILIA +BRAZIL EAST 2 H BEHIND UTC COASTAL STATES, RIO, SAO +BRAZIL PAULO, BRASILIA OCT 23, +BRAZIL '88-FEB 11, '89 +BRAZIL (ESTIMATED) +BRAZIL 2 H BEHIND UTC ATLANTIC ISLANDS, FERNANDO +BRAZIL DE NORONHA +BRAZIL 1 H BEHIND UTC OCT 23, '88-FEB 11, '89 +BRAZIL (ESTIMATED) +BRAZIL 3 H BEHIND UTC FOR MOST MAJOR AIRPORTS. +BRITISH VIRGIN I. 4 H BEHIND UTC +BRUNEI 8 H AHEAD OF UTC +BULGARIA 2 H AHEAD OF UTC +BULGARIA 3 H AHEAD OF UTC MAR 27 - SEP 24 +BURKINA FASO ON UTC +BURMA 6.5H AHEAD OF UTC +BURUNDI 2 H AHEAD OF UTC +CAMBODIA SEE KAMPUCHEA +CAMEROON 1 H AHEAD OF UTC +CANADA NEW FDL 3.5H BEHIND UTC ST.JOHN'S +CANADA NEW FDL 1.5H BEHIND UTC APR 3 - OCT 29 +CANADA ATLANTIC 4 H BEHIND UTC HALIFAX +CANADA ATLANTIC 3 H BEHIND UTC APR 3 - OCT 29 +CANADA EASTERN 5 H BEHIND UTC TORONTO, MONTREAL, OTTAWA +CANADA EASTERN 4 H BEHIND UTC APR 3 - OCT 29 +CANADA CENTRAL 6 H BEHIND UTC REGINA, WINNIPEG +CANADA CENTRAL 5 H BEHIND UTC APR 3 - OCT 29 +CANADA MOUNTAIN 7 H BEHIND UTC CALGARY, EDMONTON +CANADA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 29 +CANADA PACIFIC 8 H BEHIND UTC VANCOUVER +CANADA PACIFIC 7 H BEHIND UTC APR 3 - OCT 29 +CANADA YUKON SAME AS PACIFIC DAWSON +CAPE VERDE 1 H BEHIND UTC +CAYMAN ISLANDS 5 H BEHIND UTC +CAROLINE ISLAND 10 H AHEAD OF UTC EXCLUDING PONAPE IS., +CAROLINE ISLAND KUSAIE, AND PINGELAP +CENTRAL AFRICA 1 H AHEAD OF UTC +CEYLON 5.5H AHEAD OF UTC, SEE SRI LANKA +CHAD 1 H AHEAD OF UTC +CHANNEL ISLANDS SEE ENGLAND +CHILE 4 H BEHIND UTC CONTINENTAL +CHILE 3 H BEHIND UTC OCT 9, '88-MAR 11, '89 +CHILE 6 H BEHIND UTC EASTER ISLAND +CHILE 5 H BEHIND UTC OCT 9, '88-MAR 11, '89 +CHINA 8 H AHEAD OF UTC ALL OF CHINA, INCL TAIWAN +CHINA 9 H AHEAD OF UTC APR 17 - SEP 10 +COCOS (Keeling) I. 6.5H AHEAD OF UTC +COLOMBIA 5 H BEHIND UTC +COMOROS 3 H AHEAD OF UTC +CONGO 1 H AHEAD OF UTC +COOK ISLANDS 10 H BEHIND UTC +COOK ISLANDS 9.5H BEHIND UTC OCT 30, '88-MAR 24, '89 +COOK ISLANDS (ESTIMATED) +COSTA RICA 6 H BEHIND UTC +COTE D'IVOIRE ON UTC +CUBA 5 H BEHIND UTC +CUBA 4 H BEHIND UTC MAR 20 - OCT 8 +CURACAO 4 H BEHIND UTC ALSO BONAIRE, ARUBA, +CURACAO ST.MAARTEN +CYPRUS 2 H AHEAD OF UTC +CYPRUS 3 H AHEAD OF UTC MAR 27 - SEP 24 +CZECHOSLOVAKIA 1 H AHEAD OF UTC +CZECHOSLOVAKIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +DENMARK 1 H AHEAD OF UTC +DENMARK 2 H AHEAD OF UTC MAR 27 - SEP 24 +DENMK. FAEROE IS 1 H AHEAD OF UTC MAR 27 - SEP 24 +DJIBOUTI 3 H AHEAD OF UTC +DOMINICA 4 H BEHIND UTC +DOMINICAN REP 4 H BEHIND UTC +ECUADOR 5 H BEHIND UTC CONTINENTAL +ECUADOR 6 H BEHIND UTC GALAPAGOS ISLANDS +EGYPT 2 H AHEAD OF UTC +EGYPT 3 H AHEAD OF UTC MAY 17 - SEP 30 (AFTER +EGYPT RAMADAN) +EL SALVADOR 6 H BEHIND UTC +ENGLAND ON UTC (WALES, SCOTLAND, N.I., +ENGLAND CH. IS.) +ENGLAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +EQUATORIAL GUINEA 1 H AHEAD OF UTC +ETHIOPIA 3 H AHEAD OF UTC +FALKLAND ISLANDS 4 H BEHIND UTC +FALKLAND ISLANDS 3 H BEHIND UTC SEP 11, '88-APR 15, '89 +FALKLAND ISLANDS (ESTIMATED) +FAROE ISLAND ON UTC +FAROE ISLAND 1 H AHEAD OF UTC MAR 27 - SEP 24 +FIJI 12 H AHEAD OF UTC +FINLAND 2 H AHEAD OF UTC +FINLAND 3 H AHEAD OF UTC MAR 27 - SEP 24 +FRANCE 1 H AHEAD OF UTC +FRANCE 2 H AHEAD OF UTC MAR 27 - SEP 24 +FRENCH GUIANA 3 H BEHIND UTC +FRENCH POLYNESIA 9 H BEHIND UTC GAMBIER ISLAND +FRENCH POLYNESIA 9.5H BEHIND UTC MARQUESAS ISLANDS +FRENCH POLYNESIA 10 H BEHIND UTC SOCIETY ISLANDS, TUBUAI +FRENCH POLYNESIA ISLANDS, TUAMOTU ISLAND, +FRENCH POLYNESIA TAHITI +GABON 1 H AHEAD OF UTC +GAMBIA ON UTC +GERMANY ALL 1 H AHEAD OF UTC +GERMANY ALL 2 H AHEAD OF UTC MAR 27 - SEP 24 +GHANA ON UTC +GIBRALTAR 1 H AHEAD OF UTC +GIBRALTAR 2 H AHEAD OF UTC MAR 27 - SEP 24 +GREECE 2 H AHEAD OF UTC +GREECE 3 H AHEAD OF UTC MAR 27 - SEP 24 +GREENLAND 4 H BEHIND UTC THULE AIRBASE YEAR ROUND +GREENLAND 3 H BEHIND UTC ANGMAGSSALIK AND W. COAST +GREENLAND 2 H BEHIND UTC MAR 27 - SEP 24 +GREENLAND 1 H BEHIND UTC SCORESBYSUND +GREENLAND ON UTC MAR 27 - SEP 24 +GRENADA 4 H BEHIND UTC +GUADELOUPE 4 H BEHIND UTC ST. BARTHELEMY, NORTHERN +GUADELOUPE ST. MARTIN MARTINIQUE +GUAM 10 H AHEAD OF UTC +GUATEMALA 6 H BEHIND UTC +GUINEA ON UTC +GUINEA BISSAU ON UTC +GUINEA REPUBLIC ON UTC +GUINEA EQUATORIAL 1 H AHEAD OF UTC +GUYANA 3 H BEHIND UTC +HAITI 5 H BEHIND UTC +HAITI 4 H BEHIND UTC APR 3 - OCT 29 +HOLLAND SEE NETHERLANDS +HONDURAS 6 H BEHIND UTC +HONG KONG 8 H AHEAD OF UTC +HUNGARY 1 H AHEAD OF UTC +HUNGARY 2 H AHEAD OF UTC MAR 27 - SEP 24 +ICELAND ON UTC +INDIA 5.5H AHEAD OF UTC INCLUDING ANDAMAN ISLANDS +INDONESIA WEST 7 H AHEAD OF UTC SUMATRA, JAVA, BALI, +INDONESIA WEST JAKARTA +INDONESIA CENTRAL 8 H AHEAD OF UTC KALIMANTAN, SULAWESI +INDONESIA EAST 9 H AHEAD OF UTC IRIAN, BARAT +IRAN 3.5H AHEAD OF UTC +IRAQ 3 H AHEAD OF UTC +IRAQ 4 H AHEAD OF UTC APR 1 - SEP 30 +IRELAND ON UTC +IRELAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +ISRAEL 2 H AHEAD OF UTC +ISRAEL 3 H AHEAD OF UTC APR 10 - SEP 3 +ITALY 1 H AHEAD OF UTC +ITALY 2 H AHEAD OF UTC MAR 27 - SEP 24 +IVORY COAST ON UTC +JAMAICA 5 H BEHIND UTC +JAPAN 9 H AHEAD OF UTC +JOHNSTON ISLAND 10 H BEHIND UTC +JORDAN 2 H AHEAD OF UTC +JORDAN 3 H AHEAD OF UTC APR 1 - OCT 6 +KAMPUCHEA 7 H AHEAD OF UTC +KENYA 3 H AHEAD OF UTC +KIRIBATI, REP OF 12 H AHEAD OF UTC CANTON, ENDERBURY ISLANDS +KIRIBATI, REP OF 11 H AHEAD OF UTC CHRISTMAS ISLAND +KOREA 9 H AHEAD OF UTC +KOREA, REP OF 9 H AHEAD OF UTC +KOREA, REP OF 10 H AHEAD OF UTC MAY 8 - OCT 8 +KUWAIT 3 H AHEAD OF UTC +KUSAIE, PINGELAP 12 H AHEAD OF UTC INCLUDING MARSHALL IS., +KUSAIE, PINGELAP EXCLUDING KWAJALEIN) +KWAJALEIN 12 H BEHIND UTC +LAOS 7 H AHEAD OF UTC +LEBANON 2 H AHEAD OF UTC +LEBANON 3 H AHEAD OF UTC JUN 1 - OCT 31 +LEEWARD ISLANDS 4 H BEHIND UTC ANTIGUA, DOMINICA, +LEEWARD ISLANDS MONTSERRAT, ST. +LEEWARD ISLAANDS CHRISTOPHER, ST. KITTS, +LEEWARD ISLANDS NEVIS, ANGUILLA +LESOTHO 2 H AHEAD OF UTC +LIBERIA ON UTC +LIBYAN ARAB 1 H AHEAD OF UTC JAMAHIRIYA/LIBYA +LIBYAN ARAB 2 H AHEAD OF UTC APR 1 - SEP 30 JAMAHIRIYA/LIBYA +LIECHTENSTEIN 1 H AHEAD OF UTC +LIECHTENSTEIN 2 H AHEAD OF UTC MAR 27 - SEP 24 +LUXEMBOURG 1 H AHEAD OF UTC +LUXEMBOURG 2 H AHEAD OF UTC MAR 27 - SEP 24 +MACAO 8 H AHEAD OF UTC +MADAGASCAR 3 H AHEAD OF UTC +MADEIRA SEE PORTUGAL +MALAWI 2 H AHEAD OF UTC +MALAYSIA 8 H AHEAD OF UTC +MALDIVES 5 H AHEAD OF UTC +MALI ON UTC +MALTA 1 H AHEAD OF UTC +MALTA 2 H AHEAD OF UTC MAR 27 - SEP 24 +MARTINIQUE 4 H BEHIND UTC +MAURITANIA ON UTC +MAURITIUS 4 H AHEAD OF UTC +MARIANA ISLANDS 10 H AHEAD OF UTC EXCLUDING GUAM +MEXICO BAJA CAL N 7 H BEHIND UTC BAJA CALIFORNIA SUR AND +MEXICO BAJA CAL N N. PACIFIC COAST (STATES +MEXICO BAJA CAL N OF SINALOA AND SONORA) +MEXICO BAJA CAL N 8 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +MEXICO BAJA CAL N - OCT 29 +MEXICO BAJA CAL N 7 H BEHIND UTC ABOVE 28TH PARALLAL APR 3 +MEXICO BAJA CAL N - 0CT 29 +MEXICO 6 H BEHIND UTC STATES OF DURANGO, +MEXICO COAHUILA, NUEVO LEON, +MEXICO TAMAULIPAS +MEXICO 5 H BEHIND UTC STATES OF DURANGO, +MEXICO COAHUILA, NUEVO LEON, +MEXICO TAMAULIPAS APR 3 - OCT 29 +MEXICO 6 H BEHIND UTC GENERAL MEXICO, STATES OF +MEXICO CAMPECHE, QUINTANA ROO AND +MEXICO YUCATAN +MIDWAY ISLAND 11 H BEHIND UTC +MONACO 1 H AHEAD OF UTC +MONACO 2 H AHEAD OF UTC MAR 27 - SEP 24 +MONGOLIA 8 H AHEAD OF UTC +MONGOLIA 9 H AHEAD OF UTC MAR 27 - SEP 24 +MONTSERRAT 4 H BEHIND UTC +MOROCCO ON UTC +MOZAMBIQUE 2 H AHEAD OF UTC +NAMIBIA 2 H AHEAD OF UTC +NAURU, REP OF 12 H AHEAD OF UTC +NEPAL 5H45M AHEAD OF UTC +NETHERLANDS 1 H AHEAD OF UTC +NETHERLANDS 2 H AHEAD OF UTC MAR 27 - SEP 24 +NETHERLANDS 4 H BEHIND UTC ANTILLES AND SOUTHERN ST. +NETHERLANDS MAARTEN +NEW CALEDONIA 11 H AHEAD OF UTC +NEW HEBRIDES SEE VANUATU +NEW ZEALAND 12 H AHEAD OF UTC (EXCLUDING CHATHAM ISLAND) +NEW ZEALAND 13 H AHEAD OF UTC OCT 30, '88-MAR 4, '89 +NEW ZEALAND 12H45M AHEAD OF UTC CHATHAM ISLAND +NICARAGUA 6 H BEHIND UTC +NIGER 1 H AHEAD OF UTC +NIGERIA 1 H AHEAD OF UTC +NIUE ISLAND 11 H BEHIND UTC +NORFOLK ISLAND 11H30M AHEAD OF UTC +NORTHERN IRELAND ON UTC WALES, SCOTLAND, N.I., +NORTHERN IRELAND CH.IS. +NORTHERN IRELAND 1 H AHEAD OF UTC MAR 27 - OCT 22 +NORWAY 1 H AHEAD OF UTC +NORWAY 2 H AHEAD OF UTC MAR 27 - SEP 24 +OMAN 4 H AHEAD OF UTC +PACIFIC ISLAND T.T. +PALAU ISLANDS 9 H AHEAD OF UTC +PAKISTAN 5 H AHEAD OF UTC +PANAMA 5 H BEHIND UTC +PAPUA NEW GUINEA 10 H AHEAD OF UTC INCLUDING BOUGAINVILLE +PAPUA NEW GUINEA ISLAND +PARAGUAY 4 H BEHIND UTC +PARAGUAY 3 H BEHIND UTC OCT 1, '88-MAR 31, '89 +PERU 5 H BEHIND UTC +PHILIPPINES 8 H AHEAD OF UTC +PONAPE ISLAND 11 H AHEAD OF UTC +POLAND 1 H AHEAD OF UTC +POLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +PORTUGAL MAINLAND ON UTC +PORTUGAL MAINLAND 1 H AHEAD OF UTC MAR 27 - SEP 24 +PORTUGAL AZORES 1 H BEHIND UTC +PORTUGAL AZORES ON UTC MAR 27 - SEP 24 +PORTUGAL MADEIRA ON UTC +PORTUGAL MADEIRA 1 H AHEAD OF UTC MAR 27 - SEP 24 +PUERTO RICO 4 H BEHIND UTC +QATAR 3 H AHEAD OF UTC +ROMANIA 2 H AHEAD OF UTC +ROMANIA 3 H AHEAD OF UTC MAR 27 - SEP 24 +RUSSIA SEE USSR +RWANDA 2 H AHEAD OF UTC +SABA 4 H BEHIND UTC ALSO BONAIRE, CURACAO, +SAMOA 11 H BEHIND UTC +SAN MARINO 1 H AHEAD OF UTC +SAN MARINO 2 H AHEAD OF UTC MAR 27 - SEP 24 +SAN SALVADOR 6 H BEHIND UTC +SAO TOME ISLAND ON UTC AND PRINCIPE ISLAND +SAUDI ARABIA 3 H AHEAD OF UTC +SCOTLAND SEE ENGLAND +SENEGAL ON UTC +SEYCHELLES 4 H AHEAD OF UTC +SIERRA LEONE ON UTC +SINGAPORE 8 H AHEAD OF UTC +SOLOMON ISLANDS 11 H AHEAD OF UTC EXCLUDING BOUGAINVILLE +SOLOMON ISLANDS ISLAND +SOMALI 3 H AHEAD OF UTC +SOUTH AFRICA 2 H AHEAD OF UTC +SPAIN CANARY IS ON UTC +SPAIN CANARY IS 1 H AHEAD OF UTC MAR 27 - SEP 24 +SPAIN 1 H AHEAD OF UTC CONTINENTAL, BALEARIC AND +SPAIN MALLORCA ISLANDS +SPAIN 2 H AHEAD OF UTC CONTINENTAL, BALEARIC AND +SPAIN MALLORCA ISLANDS MAR 27 - +SPAIN SEP 24 +SPAIN MAINLAND 1 H AHEAD OF UTC MELILLA +SPAIN MAINLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +SRI LANKA 5H30M AHEAD OF UTC +ST. MAARTEN +ST. KITTS-NEVIS 4 H BEHIND UTC +ST. LUCIA 4 H BEHIND UTC +ST. PIERRE 3 H BEHIND UTC INCLUDING MIQUELON +ST. PIERRE 2 H BEHIND UTC INLCUDING MIQUELON APR 3 +ST. PIERRE - OCT 29 +ST. VINCENT 4 H BEHIND UTC INCLUDING THE GRENADINES +ST. HELENA ON UTC +SUDAN 2 H AHEAD OF UTC +SURINAME 3 H BEHIND UTC +SWAZILAND 2 H AHEAD OF UTC +SWEDEN 1 H AHEAD OF UTC +SWEDEN 2 H AHEAD OF UTC MAR 27 - SEP 24 +SWITZERLAND 1 H AHEAD OF UTC +SWITZERLAND 2 H AHEAD OF UTC MAR 27 - SEP 24 +SYRIA 2 H AHEAD OF UTC +SYRIA 3 H AHEAD OF UTC MAR 15 - OCT 30 +TAHITI 10 H BEHIND UTC +TAIWAN 8 H AHEAD OF UTC +TANZANIA 3 H AHEAD OF UTC +THAILAND 7 H AHEAD OF UTC +TOGO ON UTC +TRINIDAD / TOBAGO 4 H BEHIND UTC +TUNISIA 1 H AHEAD OF UTC +TUNISIA 2 H AHEAD OF UTC APR 10 - SEP 24 +TURKEY 2 H AHEAD OF UTC +TURKEY 3 H AHEAD OF UTC MAR 27 - SEP 24 +TURKS AND CAICOS 5 H BEHIND UTC +TURKS AND CAICOS 4 H BEHIND UTC APR 3 - OCT 29 +TUVALU 12 H AHEAD OF UTC +UGANDA 3 H AHEAD OF UTC +UNITED ARAB EMIR. 4 H AHEAD OF UTC ABU DHABI, DUBAI, SHARJAH, +UNITED ARAB EMIR RAS AL KHAIMAH +UNITED KINGDOM ON UTC WALES, SCOTLAND, N.I., CH. +UNITED KINGDOM IS. +UNITED KINGDOM 1 H AHEAD OF UTC MAR 27 - OCT 22 +UNITED STATES SEE USA +UPPER VOLTA ON UTC +URUGUAY 3 H BEHIND UTC +URUGUAY 2 H BEHIND UTC DEC 11, '88-FEB 25, '89 +URAGUAY (ESTIMATED) +USA EASTERN 5 H BEHIND UTC NEW YORK, WASHINGTON +USA EASTERN 4 H BEHIND UTC APR 3 - OCT 30 +USA CENTRAL 6 H BEHIND UTC CHICAGO, HOUSTON +USA CENTRAL 5 H BEHIND UTC APR 3 - OCT 30 +USA MOUNTAIN 7 H BEHIND UTC DENVER +USA MOUNTAIN 6 H BEHIND UTC APR 3 - OCT 30 +USA PACIFIC 8 H BEHIND UTC L.A., SAN FRANCISCO +USA PACIFIC 7 H BEHIND UTC APR 3 - OCT 30 +USA ALASKA STD 9 H BEHIND UTC MOST OF ALASKA (AKST) +USA ALASKA STD 8 H BEHIND UTC APR 3 - OCT 30 (AKDT) +USA ALEUTIAN 10 H BEHIND UTC ISLANDS WEST OF 170W +USA - " - 9 H BEHIND UTC APR 3 - OCT 30 +USA HAWAII 10 H BEHIND UTC +USA BERING 11 H BEHIND UTC SAMOA, MIDWAY +USA FOR SPECIFIC INFO ON USA ZONES/TIMES CALL DOT 202-426-4520 +USSR WEST EUROP 3 H AHEAD OF UTC LENINGRAD, MOSCOW +USSR WEST EUROP 4 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL EUR 4 H AHEAD OF UTC ROSTOV, BAKU +USSR CENTRAL EUR 5 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST EUROP 5 H AHEAD OF UTC SVERDLOVSK +USSR EAST EUROP 6 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST SIBERIAN 6 H AHEAD OF UTC TASHKENT, ALMA ATA +USSR WEST SIBERIAN 7 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 7 H AHEAD OF UTC NOVOSIBIRSK +USSR WEST-CENTRAL 8 H AHEAD OF UTC APR 1 - SEP 30 +USSR WEST-CENTRAL 8 H AHEAD OF UTC IRKUTSK +USSR WEST-CENTRAL 9 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 9 H AHEAD OF UTC YAKUTSK +USSR CENTRAL SIB 10 H AHEAD OF UTC APR 1 - SEP 30 +USSR CENTRAL SIB 10 H AHEAD OF UTC VLADIVOSTOK +USSR CENTRAL SIB 11 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 11 H AHEAD OF UTC MAGADAN +USSR EAST SIBERIA 12 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 12 H AHEAD OF UTC PETROPAVLOVSK +USSR EAST SIBERIA 13 H AHEAD OF UTC APR 1 - SEP 30 +USSR EAST SIBERIA 13 H AHEAD OF UTC UELEN +USSR EAST SIBERIA 14 H AHEAD OF UTC APR 1 - SEP 30 +VANUATU 11 H AHEAD OF UTC (NEW HEBRIDES) +VANUATU 12 H AHEAD OF UTC SEP 25, '88-MAR 25, '89 +VANUATU (ESTIMATED) +VATICAN 1 H AHEAD OF UTC +VATICAN 2 H AHEAD OF UTC MAR 27 - SEP 24 +VENEZUELA 4 H BEHIND UTC +VIETNAM 7 H AHEAD OF UTC +VIRGIN ISLANDS 4 H BEHIND UTC ST.CROIX, ST.THOMAS, +VIRGIN ISLANDS ST.JOHN +WAKE ISLAND 12 H AHEAD OF UTC +WALES SEE ENGLAND +WALLIS/FUTUNA IS. 12 H AHEAD OF UTC +WINDWARD ISLANDS 4 H BEHIND UTC GRENADA, ST. LUCIA +YEMEN 3 H AHEAD OF UTC BOTH REPUBLICS +YUGOSLAVIA 1 H AHEAD OF UTC +YUGOSLAVIA 2 H AHEAD OF UTC MAR 27 - SEP 24 +ZAIRE EAST 1 H AHEAD OF UTC KINSHASA MBANDAKA +ZAIRE WEST 2 H AHEAD OF UTC LUBUMBASHI, KASAI, KIVU, +ZAIRE WEST HAUT-ZAIRE, SHABA +ZAMBIA 2 H AHEAD OF UTC +ZIMBABWE 2 H AHEAD OF UTC diff --git a/unused/usno1995 b/unused/usno1995 new file mode 100644 index 000000000000..8b9ec8d601d4 --- /dev/null +++ b/unused/usno1995 @@ -0,0 +1,326 @@ +# @(#)usno1995 8.1 +# +# From Arthur David Olson (1995-12-21): +# +# Here's time zone information from the United States Naval Observatory +# via http://tycho.usno.navy.mil/tzones.html. See USNO's note at the end. +World Time Zones +For selected countries, the local standard time offset from UTC is given, +with daylight savings time where observed. +Time: Thu Dec 21 17:43:00 utc 1995 +Afghanistan: +4.5 hours +Albania: +1 hours (Local summer +2 hours) +Algeria: +1 hours (Local summer +2 hours) +American Samoa: -11 hours +Andorra: +1 hours (Local summer +2 hours) +Angola: +1 hours +Anguilla: -4 hours +Antarctica: -2 hours (Local summer -3 hours) +Antigua: -4 hours +Argentina: -3 hours +Argentina western prov: -4 hours +Armenia: +4 hours (Local summer +5 hours) +Aruba: -4 hours +Ascension: 0 hours +Australia Northern Territory: +9.5 hours +Australia Lord Howe Island: +10.5 hours (Local summer +11 hours) +Australia New South Wales: +10 hours (Local summer +11 hours) +Australia Queensland: +10 hours +Australia Victoria: +10 hours (Local summer +11 hours) +Australia Australian Captial Territory: +10 hours (Local summer +11 hours) +Australia South: +9.5 hours (Local summer +10.5 hours) +Australia Tasmania: +10 hours (Local summer +11 hours) +Australia Western: +8 hours +Austria: +1 hours (Local summer +2 hours) +Azerbajian: +3 hours +Azores: -1 hours (Local summer 0 hours) +Bahamas: -5 hours (Local summer -4 hours) +Bahrain: +3 hours +Balearic Islands: +1 hours (Local summer +2 hours) +Bangladesh: +6 hours +Barbados: -4 hours +Belarus: +2 hours (Local summer +3 hours) +Belgium: +1 hours (Local summer +2 hours) +Belize: -6 hours +Benin: +1 hours +Bermuda: -4 hours (Local summer -3 hours) +Bhutan: +6 hours +Bolivia: -4 hours +Bonaire: -4 hours +Bosnia Hercegovina: +1 hours (Local summer +2 hours) +Botswana: +2 hours +Brazil Acre: -4 hours (Local summer -5 hours) +Brazil Atlantic Islands: -1 hours (Local summer -2 hours) +Brazil East: -3 hours (Local summer -1 hours) +Brazil West: -4 hours (Local summer -3 hours) +British Virgin Islands: -4 hours +Brunei: +8 hours +Bulgaria: +2 hours (Local summer +3 hours) +Burkina Faso: 0 hours +Burundi: +2 hours +Cambodia: +7 hours +Cameroon: +1 hours +Canada Central: -6 hours (Local summer -5 hours) +Canada Eastern: -5 hours (Local summer -4 hours) +Canada Mountain: -7 hours (Local summer -6 hours) +Canada Yukon & Pacific: -8 hours (Local summer -7 hours) +Canada Atlantic: -4 hours (Local summer -3 hours) +Canada Newfoundland: -3.5 hours (Local summer -2.5 hours) +Canary Islands: 0 hours (Local summer +1 hours) +Canton Enderbury Islands: -11 hours +Cape Verde: -1 hours +Caroline Island: +11 hours +Cayman Islands: -5 hours +Central African Rep: +1 hours +Chad: +1 hours +Channel Islands: 0 hours (Local summer +1 hours) +Chatham Island: +12.75 hours (Local summer +13.75 hours) +Chile: -4 hours (Local summer -3 hours) +China People's Rep: +8 hours +Christmas Islands: -10 hours +Cocos (Keeling) Islands: ( hours (Local summer ) hours) +Colombia: -5 hours +Congo: +1 hours +Cook Islands: -10 hours +Costa Rica: -6 hours +Cote d'Ivoire: 0 hours +Croatia: +1 hours (Local summer +2 hours) +Cuba: -5 hours (Local summer -4 hours) +Curacao: -4 hours +Cyprus: +2 hours (Local summer +3 hours) +Czech Republic: +1 hours (Local summer +2 hours) +Dahomey: +1 hours +Denmark: +1 hours (Local summer +2 hours) +Djibouti: +3 hours +Dominica: -4 hours +Dominican Republic: -4 hours +Easter Island: -6 hours (Local summer -5 hours) +Ecuador: -5 hours +Egypt: +2 hours (Local summer +3 hours) +El Salvador: -6 hours +England: 0 hours (Local summer +1 hours) +Equitorial Guinea: +1 hours +Eritrea: +3 hours +Estonia: +2 hours (Local summer +3 hours) +Ethiopia: +3 hours +Falkland Islands: -4 hours (Local summer -3 hours) +Faroe Island: 0 hours (Local summer +1 hours) +Fiji: +12 hours +Finland: +2 hours (Local summer +3 hours) +France: +1 hours (Local summer +2 hours) +French Guiana: -3 hours +French Polynesia: -10 hours +Gabon: +1 hours +Galapagos Islands: -6 hours +Gambia: 0 hours +Gambier Island: -9 hours +Georgia: +4 hours +Germany: +1 hours (Local summer +2 hours) +Ghana: 0 hours +Gibraltar: +1 hours (Local summer +2 hours) +Greece: +2 hours (Local summer +3 hours) +Greenland: -3 hours (Local summer -2 hours) +Greenland Thule: -4 hours (Local summer -3 hours) +Greenland Scoresbysun: -1 hours (Local summer 0 hours) +Grenada: -4 hours +Grenadines: -4 hours +Guadeloupe: -4 hours +Guam: +10 hours +Guatemala: -6 hours +Guinea: 0 hours +Guinea Bissau: - hours (Local summer 0 hours) +Guyana: -3 hours +Haiti: -5 hours (Local summer -4 hours) +Honduras: -6 hours +Hong kong: +8 hours +Hungary: +1 hours (Local summer +2 hours) +Iceland: 0 hours +India: +5.5 hours +Indonesia Central: +8 hours +Indonesia East: +9 hours +Indonesia West: +7 hours +Iran: +3.5 hours +Iraq: +3 hours (Local summer +4 hours) +Ireland Republic of: 0 hours (Local summer +1 hours) +Israel: +2 hours (Local summer +3 hours) +Italy: +1 hours (Local summer +2 hours) +Jamaica: -5 hours +Japan: +9 hours +Johnston Island: -10 hours +Jordan: +2 hours (Local summer +3 hours) +Kazakhstan: +6 hours (Local summer +7 hours) +Kenya: +3 hours +Kiribati: +12 hours +Korea Dem Republic of: +9 hours +Korea Republic of: +9 hours +Kusaie: +12 hours +Kuwait: +3 hours +Kwajalein: -12 hours +Kyrgyzstan: +5 hours (Local summer +6 hours) +Laos: +7 hours +Latvia: +2 hours (Local summer +3 hours) +Lebanon: +2 hours (Local summer +3 hours) +Leeward Islands: -4 hours +Lesotho: +2 hours +Liberia: 0 hours +Libya: +2 hours +Lithuania: +2 hours (Local summer +3 hours) +Luxembourg: +1 hours (Local summer +2 hours) +Macedonia: +1 hours (Local summer +2 hours) +Madagascar: +3 hours +Madeira: 0 hours (Local summer +1 hours) +Malawi: +2 hours +Malaysia: +8 hours +Maldives: +5 hours +Mali: 0 hours +Mallorca Islands: +1 hours (Local summer +2 hours) +Malta: +1 hours (Local summer +2 hours) +Mariana Island: +10 hours +Marquesas Islands: -9.5 hours +Marshall Islands: +12 hours +Martinique: -4 hours +Mauritania: 0 hours +Mauritius: +4 hours +Mayotte: +3 hours +Melilla: +1 hours (Local summer +2 hours) +Mexico: -6 hours +Mexico Baja Calif Norte: -8 hours (Local summer -7 hours) +Mexico Nayarit: -7 hours +Mexico Sinaloa: -7 hours +Mexico Sonora: -7 hours +Midway Island: -11 hours +Moldova: +2 hours (Local summer +3 hours) +Moldovian Rep Pridnestrovye: +2 hours (Local summer +3 hours) +Monaco: +1 hours (Local summer +2 hours) +Mongolia: +8 hours +Morocco: 0 hours +Mozambique: +2 hours +Myanmar: +6.5 hours +Namibia: +1 hours (Local summer +2 hours) +Nauru Republic of: +12 hours +Nepal: +5.75 hours +Netherlands: +1 hours (Local summer +2 hours) +Netherlands Antilles: -4 hours +Nevis Montserrat: -4 hours +New Caledonia: +11 hours +New Hebrides: +11 hours +New Zealand: +12 hours (Local summer +13 hours) +Nicaragua: -6 hours (Local summer -5 hours) +Niger: +1 hours +Nigeria: +1 hours +Niue Island: -11 hours +Norfolk Island: +11.5 hours +Northern Ireland: 0 hours (Local summer +1 hours) +Northern Mariana Islands: +10 hours +Norway: +1 hours (Local summer +2 hours) +Oman: +4 hours +Pakistan: +5 hours +Palau: +9 hours +Panama: -5 hours +Papua New Guinea: +10 hours +Paraguay: -4 hours (Local summer -3 hours) +Peru: -5 hours +Philippines: +8 hours +Pingelap: +12 hours +Poland: +1 hours (Local summer +2 hours) +Ponape Island: +11 hours +Portugal: +1 hours (Local summer +2 hours) +Principe Island: 0 hours +Puerto Rico: -4 hours +Qatar: +3 hours +Reunion: +4 hours +Romania: +2 hours (Local summer +3 hours) +Russian Federation zone eight: +9 hours (Local summer +10 hours) +Russian Federation zone eleven: +12 hours (Local summer +13 hours) +Russian Federation zone five: +6 hours (Local summer +7 hours) +Russian Federation zone four: +5 hours (Local summer +6 hours) +Russian Federation zone nine: +10 hours (Local summer +11 hours) +Russian Federation zone one: +2 hours (Local summer +3 hours) +Russian Federation zone seven: +8 hours (Local summer +9 hours) +Russian Federation zone six: +7 hours (Local summer +8 hours) +Russian Federation zone ten: +11 hours (Local summer +12 hours) +Russian Federation zone three: +4 hours (Local summer +5 hours) +Russian Federation zone two: +4 hours (Local summer +5 hours) +Rwanda: +2 hours +Saba: -4 hours +Samoa: -11 hours +San Marino: +1 hours (Local summer +2 hours) +Sao Tome e Principe: 0 hours +Saudi Arabia: +3 hours +Scotland: 0 hours +Senegal: 0 hours +Seychelles: +4 hours +Sierra Leone: 0 hours +Singapore: +8 hours +Slovakia: +1 hours (Local summer +2 hours) +Slovenia: +1 hours (Local summer +2 hours) +Society Island: -10 hours +Solomon Islands: +11 hours +Somalia: +3 hours +South Africa: +2 hours +Spain: +1 hours (Local summer +2 hours) +Sri Lanka: +5.5 hours +St Christopher: -4 hours +St Croix: -4 hours +St Helena: 0 hours +St John: -4 hours +St Kitts Nevis: -4 hours +St Lucia: -4 hours +St Maarten: -4 hours +St Pierre & Miquelon: -3 hours (Local summer -2 hours) +St Thomas: -4 hours +St Vincent: -4 hours +Sudan: +2 hours +Suriname: -3 hours +Swaziland: +2 hours +Sweden: +1 hours (Local summer +2 hours) +Switzerland: +1 hours (Local summer +2 hours) +Syria: +2 hours (Local summer +3 hours) +Tahiti: -10 hours +Taiwan: +8 hours +Tajikistan: +6 hours +Tanzania: +3 hours +Thailand: +7 hours +Togo: 0 hours +Tonga: +13 hours +Trinidad and Tobago: -4 hours +Tuamotu Island: -10 hours +Tubuai Island: -10 hours +Tunisia: +1 hours +Turkey: +2 hours (Local summer +3 hours) +Turkmenistan: +5 hours +Turks and Caicos Islands: -5 hours (Local summer -4 hours) +Tuvalu: +12 hours +Uganda: +3 hours +Ukraine: +2 hours (Local summer +3 hours) +United Arab Emirates: +4 hours +United Kingdom: 0 hours (Local summer +1 hours) +USA Central: -6 hours (Local summer -5 hours) +USA Eastern: -5 hours (Local summer -4 hours) +USA Mountain: -7 hours (Local summer -6 hours) +USA Arizona: -7 hours +USA Indiana East: -5 hours +USA Pacific: -8 hours (Local summer -7 hours) +USA Alaska: -9 hours (Local summer -8 hours) +USA Hawaii Aleutian: - hours (Local summer -10 hours) +Uruguay: -3 hours +Uzbekistan: +5 hours +Vanuatu: +11 hours (Local summer +12 hours) +Vatican City: +1 hours (Local summer +2 hours) +Venezuela: -4 hours +Vietnam: +7 hours +Virgin Islands: -4 hours +Wake Island: +12 hours +Wales: 0 hours (Local summer +1 hours) +Wallis and Futuna Islands: +12 hours +Windward Islands: -4 hours +Yemen: +3 hours +Yugoslavia: +1 hours (Local summer +2 hours) +Zaire Kasai: +2 hours +Zaire Kinshasa Mbandaka: +1 hours +Zaire Haut Zaire: +2 hours +Zaire Kivu: +2 hours +Zaire Shaba: +2 hours +Zambia: +2 hours +Zimbabwe: +2 hours +All timezone information is non-authoritative... diff --git a/unused/usno1997 b/unused/usno1997 new file mode 100644 index 000000000000..e18fcdfcdcbf --- /dev/null +++ b/unused/usno1997 @@ -0,0 +1,327 @@ +# @(#)usno1997 8.1 +# +# From Arthur David Olson (1997-03-07): +# +# Here's time zone information from the United States Naval Observatory +# via http://tycho.usno.navy.mil/tzones.html. See USNO's note at the end. +Unofficial Time Zone Information +World Time Zones +For selected countries, the local standard time offset from UTC is given, with daylight savings time where observed. +Time: Fri Mar 7 22:38:58 UTC 1997 +Afghanistan: +4.5 hours +Albania: +1 hours (Local summer +2 hours) +Algeria: +1 hours (Local summer +2 hours) +American Samoa: -11 hours +Andorra: +1 hours (Local summer +2 hours) +Angola: +1 hours +Anguilla: -4 hours +Antarctica: -2 hours (Local summer -3 hours) +Antigua: -4 hours +Argentina: -3 hours +Argentina western prov: -4 hours +Armenia: +4 hours (Local summer +5 hours) +Aruba: -4 hours +Ascension: 0 hours +Australia Northern Territory: +9.5 hours +Australia Lord Howe Island: +10.5 hours (Local summer +11 hours) +Australia New South Wales: +10 hours (Local summer +11 hours) +Australia Queensland: +10 hours +Australia Victoria: +10 hours (Local summer +11 hours) +Australia Australian Captial Territory: +10 hours (Local summer +11 hours) +Australia South: +9.5 hours (Local summer +10.5 hours) +Australia Tasmania: +10 hours (Local summer +11 hours) +Australia Western: +8 hours +Austria: +1 hours (Local summer +2 hours) +Azerbajian: +3 hours +Azores: -1 hours (Local summer 0 hours) +Bahamas: -5 hours (Local summer -4 hours) +Bahrain: +3 hours +Balearic Islands: +1 hours (Local summer +2 hours) +Bangladesh: +6 hours +Barbados: -4 hours +Belarus: +2 hours (Local summer +3 hours) +Belgium: +1 hours (Local summer +2 hours) +Belize: -6 hours +Benin: +1 hours +Bermuda: -4 hours (Local summer -3 hours) +Bhutan: +6 hours +Bolivia: -4 hours +Bonaire: -4 hours +Bosnia Hercegovina: +1 hours (Local summer +2 hours) +Botswana: +2 hours +Brazil Acre: -4 hours (Local summer -5 hours) +Brazil Atlantic Islands: -1 hours (Local summer -2 hours) +Brazil East: -3 hours (Local summer -1 hours) +Brazil West: -4 hours (Local summer -3 hours) +British Virgin Islands: -4 hours +Brunei: +8 hours +Bulgaria: +2 hours (Local summer +3 hours) +Burkina Faso: 0 hours +Burundi: +2 hours +Cambodia: +7 hours +Cameroon: +1 hours +Canada Central: -6 hours (Local summer -5 hours) +Canada Eastern: -5 hours (Local summer -4 hours) +Canada Mountain: -7 hours (Local summer -6 hours) +Canada Yukon & Pacific: -8 hours (Local summer -7 hours) +Canada Atlantic: -4 hours (Local summer -3 hours) +Canada Newfoundland: -3.5 hours (Local summer -2.5 hours) +Canary Islands: 0 hours (Local summer +1 hours) +Canton Enderbury Islands: -11 hours +Cape Verde: -1 hours +Caroline Island: +11 hours +Cayman Islands: -5 hours +Central African Rep: +1 hours +Chad: +1 hours +Channel Islands: 0 hours (Local summer +1 hours) +Chatham Island: +12.75 hours (Local summer +13.75 hours) +Chile: -4 hours (Local summer -3 hours) +China People's Rep: +8 hours +Christmas Islands: -10 hours +Cocos (Keeling) Islands: ( hours (Local summer ) hours) +Colombia: -5 hours +Congo: +1 hours +Cook Islands: -10 hours +Costa Rica: -6 hours +Cote d'Ivoire: 0 hours +Croatia: +1 hours (Local summer +2 hours) +Cuba: -5 hours (Local summer -4 hours) +Curacao: -4 hours +Cyprus: +2 hours (Local summer +3 hours) +Czech Republic: +1 hours (Local summer +2 hours) +Dahomey: +1 hours +Denmark: +1 hours (Local summer +2 hours) +Djibouti: +3 hours +Dominica: -4 hours +Dominican Republic: -4 hours +Easter Island: -6 hours (Local summer -5 hours) +Ecuador: -5 hours +Egypt: +2 hours (Local summer +3 hours) +El Salvador: -6 hours +England: 0 hours (Local summer +1 hours) +Equitorial Guinea: +1 hours +Eritrea: +3 hours +Estonia: +2 hours (Local summer +3 hours) +Ethiopia: +3 hours +Falkland Islands: -4 hours (Local summer -3 hours) +Faroe Island: 0 hours (Local summer +1 hours) +Fiji: +12 hours +Finland: +2 hours (Local summer +3 hours) +France: +1 hours (Local summer +2 hours) +French Guiana: -3 hours +French Polynesia: -10 hours +Gabon: +1 hours +Galapagos Islands: -5 hours +Gambia: 0 hours +Gambier Island: -9 hours +Georgia: +4 hours +Germany: +1 hours (Local summer +2 hours) +Ghana: 0 hours +Gibraltar: +1 hours (Local summer +2 hours) +Greece: +2 hours (Local summer +3 hours) +Greenland: -3 hours (Local summer -2 hours) +Greenland Thule: -4 hours (Local summer -3 hours) +Greenland Scoresbysun: -1 hours (Local summer 0 hours) +Grenada: -4 hours +Grenadines: -4 hours +Guadeloupe: -4 hours +Guam: +10 hours +Guatemala: -6 hours +Guinea: 0 hours +Guinea Bissau: - hours (Local summer 0 hours) +Guyana: -3 hours +Haiti: -5 hours (Local summer -4 hours) +Honduras: -6 hours +Hong kong: +8 hours +Hungary: +1 hours (Local summer +2 hours) +Iceland: 0 hours +India: +5.5 hours +Indonesia Central: +8 hours +Indonesia East: +9 hours +Indonesia West: +7 hours +Iran: +3.5 hours +Iraq: +3 hours (Local summer +4 hours) +Ireland Republic of: 0 hours (Local summer +1 hours) +Israel: +2 hours (Local summer +3 hours) +Italy: +1 hours (Local summer +2 hours) +Jamaica: -5 hours +Japan: +9 hours +Johnston Island: -10 hours +Jordan: +2 hours (Local summer +3 hours) +Kazakhstan: +6 hours (Local summer +7 hours) +Kenya: +3 hours +Kiribati: +12 hours +Korea Dem Republic of: +9 hours +Korea Republic of: +9 hours +Kusaie: +12 hours +Kuwait: +3 hours +Kwajalein: -12 hours +Kyrgyzstan: +5 hours (Local summer +6 hours) +Laos: +7 hours +Latvia: +2 hours (Local summer +3 hours) +Lebanon: +2 hours (Local summer +3 hours) +Leeward Islands: -4 hours +Lesotho: +2 hours +Liberia: 0 hours +Libya: +2 hours +Lithuania: +2 hours (Local summer +3 hours) +Luxembourg: +1 hours (Local summer +2 hours) +Macedonia: +1 hours (Local summer +2 hours) +Madagascar: +3 hours +Madeira: 0 hours (Local summer +1 hours) +Malawi: +2 hours +Malaysia: +8 hours +Maldives: +5 hours +Mali: 0 hours +Mallorca Islands: +1 hours (Local summer +2 hours) +Malta: +1 hours (Local summer +2 hours) +Mariana Island: +10 hours +Marquesas Islands: -9.5 hours +Marshall Islands: +12 hours +Martinique: -4 hours +Mauritania: 0 hours +Mauritius: +4 hours +Mayotte: +3 hours +Melilla: +1 hours (Local summer +2 hours) +Mexico: -6 hours +Mexico Baja Calif Norte: -8 hours (Local summer -7 hours) +Mexico Nayarit: -7 hours +Mexico Sinaloa: -7 hours +Mexico Sonora: -7 hours +Midway Island: -11 hours +Moldova: +2 hours (Local summer +3 hours) +Moldovian Rep Pridnestrovye: +2 hours (Local summer +3 hours) +Monaco: +1 hours (Local summer +2 hours) +Mongolia: +8 hours +Morocco: 0 hours +Mozambique: +2 hours +Myanmar: +6.5 hours +Namibia: +1 hours (Local summer +2 hours) +Nauru Republic of: +12 hours +Nepal: +5.75 hours +Netherlands: +1 hours (Local summer +2 hours) +Netherlands Antilles: -4 hours +Nevis Montserrat: -4 hours +New Caledonia: +11 hours +New Hebrides: +11 hours +New Zealand: +12 hours (Local summer +13 hours) +Nicaragua: -6 hours (Local summer -5 hours) +Niger: +1 hours +Nigeria: +1 hours +Niue Island: -11 hours +Norfolk Island: +11.5 hours +Northern Ireland: 0 hours (Local summer +1 hours) +Northern Mariana Islands: +10 hours +Norway: +1 hours (Local summer +2 hours) +Oman: +4 hours +Pakistan: +5 hours +Palau: +9 hours +Panama: -5 hours +Papua New Guinea: +10 hours +Paraguay: -4 hours (Local summer -3 hours) +Peru: -5 hours +Philippines: +8 hours +Pingelap: +12 hours +Poland: +1 hours (Local summer +2 hours) +Ponape Island: +11 hours +Portugal: +1 hours (Local summer +2 hours) +Principe Island: 0 hours +Puerto Rico: -4 hours +Qatar: +3 hours +Reunion: +4 hours +Romania: +2 hours (Local summer +3 hours) +Russian Federation zone eight: +9 hours (Local summer +10 hours) +Russian Federation zone eleven: +12 hours (Local summer +13 hours) +Russian Federation zone five: +6 hours (Local summer +7 hours) +Russian Federation zone four: +5 hours (Local summer +6 hours) +Russian Federation zone nine: +10 hours (Local summer +11 hours) +Russian Federation zone one: +2 hours (Local summer +3 hours) +Russian Federation zone seven: +8 hours (Local summer +9 hours) +Russian Federation zone six: +7 hours (Local summer +8 hours) +Russian Federation zone ten: +11 hours (Local summer +12 hours) +Russian Federation zone three: +4 hours (Local summer +5 hours) +Russian Federation zone two: +4 hours (Local summer +5 hours) +Rwanda: +2 hours +Saba: -4 hours +Samoa: -11 hours +San Marino: +1 hours (Local summer +2 hours) +Sao Tome e Principe: 0 hours +Saudi Arabia: +3 hours +Scotland: 0 hours (Local summer +1 hours) +Senegal: 0 hours +Seychelles: +4 hours +Sierra Leone: 0 hours +Singapore: +8 hours +Slovakia: +1 hours (Local summer +2 hours) +Slovenia: +1 hours (Local summer +2 hours) +Society Island: -10 hours +Solomon Islands: +11 hours +Somalia: +3 hours +South Africa: +2 hours +Spain: +1 hours (Local summer +2 hours) +Sri Lanka: +5.5 hours +St Christopher: -4 hours +St Croix: -4 hours +St Helena: 0 hours +St John: -4 hours +St Kitts Nevis: -4 hours +St Lucia: -4 hours +St Maarten: -4 hours +St Pierre & Miquelon: -3 hours (Local summer -2 hours) +St Thomas: -4 hours +St Vincent: -4 hours +Sudan: +2 hours +Suriname: -3 hours +Swaziland: +2 hours +Sweden: +1 hours (Local summer +2 hours) +Switzerland: +1 hours (Local summer +2 hours) +Syria: +2 hours (Local summer +3 hours) +Tahiti: -10 hours +Taiwan: +8 hours +Tajikistan: +6 hours +Tanzania: +3 hours +Thailand: +7 hours +Togo: 0 hours +Tonga: +13 hours +Trinidad and Tobago: -4 hours +Tuamotu Island: -10 hours +Tubuai Island: -10 hours +Tunisia: +1 hours +Turkey: +2 hours (Local summer +3 hours) +Turkmenistan: +5 hours +Turks and Caicos Islands: -5 hours (Local summer -4 hours) +Tuvalu: +12 hours +Uganda: +3 hours +Ukraine: +2 hours (Local summer +3 hours) +United Arab Emirates: +4 hours +United Kingdom: 0 hours (Local summer +1 hours) +USA Central: -6 hours (Local summer -5 hours) +USA Eastern: -5 hours (Local summer -4 hours) +USA Mountain: -7 hours (Local summer -6 hours) +USA Arizona: -7 hours +USA Indiana East: -5 hours +USA Pacific: -8 hours (Local summer -7 hours) +USA Alaska: -9 hours (Local summer -8 hours) +USA Aleutian: -10 hours +USA Hawaii: -10 hours +Uruguay: -3 hours +Uzbekistan: +5 hours +Vanuatu: +11 hours (Local summer +12 hours) +Vatican City: +1 hours (Local summer +2 hours) +Venezuela: -4 hours +Vietnam: +7 hours +Virgin Islands: -4 hours +Wake Island: +12 hours +Wales: 0 hours (Local summer +1 hours) +Wallis and Futuna Islands: +12 hours +Windward Islands: -4 hours +Yemen: +3 hours +Yugoslavia: +1 hours (Local summer +2 hours) +Zaire Kasai: +2 hours +Zaire Kinshasa Mbandaka: +1 hours +Zaire Haut Zaire: +2 hours +Zaire Kivu: +2 hours +Zaire Shaba: +2 hours +Zambia: +2 hours +Zimbabwe: +2 hours +All timezone information is non-authoritative... diff --git a/unused/usno1998 b/unused/usno1998 new file mode 100644 index 000000000000..c3c6991aa61e --- /dev/null +++ b/unused/usno1998 @@ -0,0 +1,327 @@ +# @(#)usno1998 8.1 +# +# From Arthur David Olson (1998-05-26): +# +# Here's time zone information from the United States Naval Observatory +# via http://tycho.usno.navy.mil/tzones.html. See USNO's note at the end. +Unofficial Time Zone Information +World Time Zones +For selected countries, the local standard time offset from UTC is given, with daylight savings time where observed. +Time: Mon May 25 21:14:24 UTC 1998 +Afghanistan: +4.5 hours +Albania: +1 hours (Local summer +2 hours) +Algeria: +1 hours (Local summer +2 hours) +American Samoa: -11 hours +Andorra: +1 hours (Local summer +2 hours) +Angola: +1 hours +Anguilla: -4 hours +Antarctica: -2 hours (Local summer -3 hours) +Antigua: -4 hours +Argentina: -3 hours +Argentina western prov: -4 hours +Armenia: +4 hours (Local summer +5 hours) +Aruba: -4 hours +Ascension: 0 hours +Australia Northern Territory: +9.5 hours +Australia Lord Howe Island: +10.5 hours (Local summer +11 hours) +Australia New South Wales: +10 hours (Local summer +11 hours) +Australia Queensland: +10 hours +Australia Victoria: +10 hours (Local summer +11 hours) +Australia Australian Captial Territory: +10 hours (Local summer +11 hours) +Australia South: +9.5 hours (Local summer +10.5 hours) +Australia Tasmania: +10 hours (Local summer +11 hours) +Australia Western: +8 hours +Austria: +1 hours (Local summer +2 hours) +Azerbajian: +3 hours +Azores: -1 hours (Local summer 0 hours) +Bahamas: -5 hours (Local summer -4 hours) +Bahrain: +3 hours +Balearic Islands: +1 hours (Local summer +2 hours) +Bangladesh: +6 hours +Barbados: -4 hours +Belarus: +2 hours (Local summer +3 hours) +Belgium: +1 hours (Local summer +2 hours) +Belize: -6 hours +Benin: +1 hours +Bermuda: -4 hours (Local summer -3 hours) +Bhutan: +6 hours +Bolivia: -4 hours +Bonaire: -4 hours +Bosnia Hercegovina: +1 hours (Local summer +2 hours) +Botswana: +2 hours +Brazil Acre: -4 hours (Local summer -5 hours) +Brazil Atlantic Islands: -1 hours (Local summer -2 hours) +Brazil East: -3 hours (Local summer -1 hours) +Brazil West: -4 hours (Local summer -3 hours) +British Virgin Islands: -4 hours +Brunei: +8 hours +Bulgaria: +2 hours (Local summer +3 hours) +Burkina Faso: 0 hours +Burundi: +2 hours +Cambodia: +7 hours +Cameroon: +1 hours +Canada Central: -6 hours (Local summer -5 hours) +Canada Eastern: -5 hours (Local summer -4 hours) +Canada Mountain: -7 hours (Local summer -6 hours) +Canada Yukon & Pacific: -8 hours (Local summer -7 hours) +Canada Atlantic: -4 hours (Local summer -3 hours) +Canada Newfoundland: -3.5 hours (Local summer -2.5 hours) +Canary Islands: 0 hours (Local summer +1 hours) +Canton Enderbury Islands: -11 hours +Cape Verde: -1 hours +Caroline Island: +11 hours +Cayman Islands: -5 hours +Central African Rep: +1 hours +Chad: +1 hours +Channel Islands: 0 hours (Local summer +1 hours) +Chatham Island: +12.75 hours (Local summer +13.75 hours) +Chile: -4 hours (Local summer -3 hours) +China People's Rep: +8 hours +Christmas Islands: -10 hours +Cocos (Keeling) Islands: ( hours (Local summer ) hours) +Colombia: -5 hours +Congo: +1 hours +Cook Islands: -10 hours +Costa Rica: -6 hours +Cote d'Ivoire: 0 hours +Croatia: +1 hours (Local summer +2 hours) +Cuba: -5 hours (Local summer -4 hours) +Curacao: -4 hours +Cyprus: +2 hours (Local summer +3 hours) +Czech Republic: +1 hours (Local summer +2 hours) +Dahomey: +1 hours +Denmark: +1 hours (Local summer +2 hours) +Djibouti: +3 hours +Dominica: -4 hours +Dominican Republic: -4 hours +Easter Island: -6 hours (Local summer -5 hours) +Ecuador: -5 hours +Egypt: +2 hours (Local summer +3 hours) +El Salvador: -6 hours +England: 0 hours (Local summer +1 hours) +Equitorial Guinea: +1 hours +Eritrea: +3 hours +Estonia: +2 hours (Local summer +3 hours) +Ethiopia: +3 hours +Falkland Islands: -4 hours (Local summer -3 hours) +Faroe Island: 0 hours (Local summer +1 hours) +Fiji: +12 hours +Finland: +2 hours (Local summer +3 hours) +France: +1 hours (Local summer +2 hours) +French Guiana: -3 hours +French Polynesia: -10 hours +Gabon: +1 hours +Galapagos Islands: -5 hours +Gambia: 0 hours +Gambier Island: -9 hours +Georgia: +4 hours +Germany: +1 hours (Local summer +2 hours) +Ghana: 0 hours +Gibraltar: +1 hours (Local summer +2 hours) +Greece: +2 hours (Local summer +3 hours) +Greenland: -3 hours (Local summer -2 hours) +Greenland Thule: -4 hours (Local summer -3 hours) +Greenland Scoresbysun: -1 hours (Local summer 0 hours) +Grenada: -4 hours +Grenadines: -4 hours +Guadeloupe: -4 hours +Guam: +10 hours +Guatemala: -6 hours +Guinea: 0 hours +Guinea Bissau: - hours (Local summer 0 hours) +Guyana: -3 hours +Haiti: -5 hours (Local summer -4 hours) +Honduras: -6 hours +Hong kong: +8 hours +Hungary: +1 hours (Local summer +2 hours) +Iceland: 0 hours +India: +5.5 hours +Indonesia Central: +8 hours +Indonesia East: +9 hours +Indonesia West: +7 hours +Iran: +3.5 hours +Iraq: +3 hours (Local summer +4 hours) +Ireland Republic of: 0 hours (Local summer +1 hours) +Israel: +2 hours (Local summer +3 hours) +Italy: +1 hours (Local summer +2 hours) +Jamaica: -5 hours +Japan: +9 hours +Johnston Island: -10 hours +Jordan: +2 hours (Local summer +3 hours) +Kazakhstan: +6 hours (Local summer +7 hours) +Kenya: +3 hours +Kiribati: +12 hours +Korea Dem Republic of: +9 hours +Korea Republic of: +9 hours +Kusaie: +12 hours +Kuwait: +3 hours +Kwajalein: -12 hours +Kyrgyzstan: +5 hours (Local summer +6 hours) +Laos: +7 hours +Latvia: +2 hours (Local summer +3 hours) +Lebanon: +2 hours (Local summer +3 hours) +Leeward Islands: -4 hours +Lesotho: +2 hours +Liberia: 0 hours +Libya: +2 hours +Lithuania: +2 hours (Local summer +3 hours) +Luxembourg: +1 hours (Local summer +2 hours) +Macedonia: +1 hours (Local summer +2 hours) +Madagascar: +3 hours +Madeira: 0 hours (Local summer +1 hours) +Malawi: +2 hours +Malaysia: +8 hours +Maldives: +5 hours +Mali: 0 hours +Mallorca Islands: +1 hours (Local summer +2 hours) +Malta: +1 hours (Local summer +2 hours) +Mariana Island: +10 hours +Marquesas Islands: -9.5 hours +Marshall Islands: +12 hours +Martinique: -4 hours +Mauritania: 0 hours +Mauritius: +4 hours +Mayotte: +3 hours +Melilla: +1 hours (Local summer +2 hours) +Mexico: -6 hours +Mexico Baja Calif Norte: -8 hours (Local summer -7 hours) +Mexico Nayarit: -7 hours +Mexico Sinaloa: -7 hours +Mexico Sonora: -7 hours +Midway Island: -11 hours +Moldova: +2 hours (Local summer +3 hours) +Moldovian Rep Pridnestrovye: +2 hours (Local summer +3 hours) +Monaco: +1 hours (Local summer +2 hours) +Mongolia: +8 hours +Morocco: 0 hours +Mozambique: +2 hours +Myanmar: +6.5 hours +Namibia: +1 hours (Local summer +2 hours) +Nauru Republic of: +12 hours +Nepal: +5.75 hours +Netherlands: +1 hours (Local summer +2 hours) +Netherlands Antilles: -4 hours +Nevis Montserrat: -4 hours +New Caledonia: +11 hours +New Hebrides: +11 hours +New Zealand: +12 hours (Local summer +13 hours) +Nicaragua: -6 hours (Local summer -5 hours) +Niger: +1 hours +Nigeria: +1 hours +Niue Island: -11 hours +Norfolk Island: +11.5 hours +Northern Ireland: 0 hours (Local summer +1 hours) +Northern Mariana Islands: +10 hours +Norway: +1 hours (Local summer +2 hours) +Oman: +4 hours +Pakistan: +5 hours +Palau: +9 hours +Panama: -5 hours +Papua New Guinea: +10 hours +Paraguay: -4 hours (Local summer -3 hours) +Peru: -5 hours +Philippines: +8 hours +Pingelap: +12 hours +Poland: +1 hours (Local summer +2 hours) +Ponape Island: +11 hours +Portugal: +1 hours (Local summer +2 hours) +Principe Island: 0 hours +Puerto Rico: -4 hours +Qatar: +3 hours +Reunion: +4 hours +Romania: +2 hours (Local summer +3 hours) +Russian Federation zone eight: +9 hours (Local summer +10 hours) +Russian Federation zone eleven: +12 hours (Local summer +13 hours) +Russian Federation zone five: +6 hours (Local summer +7 hours) +Russian Federation zone four: +5 hours (Local summer +6 hours) +Russian Federation zone nine: +10 hours (Local summer +11 hours) +Russian Federation zone one: +2 hours (Local summer +3 hours) +Russian Federation zone seven: +8 hours (Local summer +9 hours) +Russian Federation zone six: +7 hours (Local summer +8 hours) +Russian Federation zone ten: +11 hours (Local summer +12 hours) +Russian Federation zone three: +4 hours (Local summer +5 hours) +Russian Federation zone two: +4 hours (Local summer +5 hours) +Rwanda: +2 hours +Saba: -4 hours +Samoa: -11 hours +San Marino: +1 hours (Local summer +2 hours) +Sao Tome e Principe: 0 hours +Saudi Arabia: +3 hours +Scotland: 0 hours (Local summer +1 hours) +Senegal: 0 hours +Seychelles: +4 hours +Sierra Leone: 0 hours +Singapore: +8 hours +Slovakia: +1 hours (Local summer +2 hours) +Slovenia: +1 hours (Local summer +2 hours) +Society Island: -10 hours +Solomon Islands: +11 hours +Somalia: +3 hours +South Africa: +2 hours +Spain: +1 hours (Local summer +2 hours) +Sri Lanka: +5.5 hours +St Christopher: -4 hours +St Croix: -4 hours +St Helena: 0 hours +St John: -4 hours +St Kitts Nevis: -4 hours +St Lucia: -4 hours +St Maarten: -4 hours +St Pierre & Miquelon: -3 hours (Local summer -2 hours) +St Thomas: -4 hours +St Vincent: -4 hours +Sudan: +2 hours +Suriname: -3 hours +Swaziland: +2 hours +Sweden: +1 hours (Local summer +2 hours) +Switzerland: +1 hours (Local summer +2 hours) +Syria: +2 hours (Local summer +3 hours) +Tahiti: -10 hours +Taiwan: +8 hours +Tajikistan: +6 hours +Tanzania: +3 hours +Thailand: +7 hours +Togo: 0 hours +Tonga: +13 hours +Trinidad and Tobago: -4 hours +Tuamotu Island: -10 hours +Tubuai Island: -10 hours +Tunisia: +1 hours +Turkey: +2 hours (Local summer +3 hours) +Turkmenistan: +5 hours +Turks and Caicos Islands: -5 hours (Local summer -4 hours) +Tuvalu: +12 hours +Uganda: +3 hours +Ukraine: +2 hours (Local summer +3 hours) +United Arab Emirates: +4 hours +United Kingdom: 0 hours (Local summer +1 hours) +USA Central: -6 hours (Local summer -5 hours) +USA Eastern: -5 hours (Local summer -4 hours) +USA Mountain: -7 hours (Local summer -6 hours) +USA Arizona: -7 hours +USA Indiana East: -5 hours +USA Pacific: -8 hours (Local summer -7 hours) +USA Alaska: -9 hours (Local summer -8 hours) +USA Aleutian: -10 hours +USA Hawaii: -10 hours +Uruguay: -3 hours +Uzbekistan: +5 hours +Vanuatu: +11 hours (Local summer +12 hours) +Vatican City: +1 hours (Local summer +2 hours) +Venezuela: -4 hours +Vietnam: +7 hours +Virgin Islands: -4 hours +Wake Island: +12 hours +Wales: 0 hours (Local summer +1 hours) +Wallis and Futuna Islands: +12 hours +Windward Islands: -4 hours +Yemen: +3 hours +Yugoslavia: +1 hours (Local summer +2 hours) +Zaire Kasai: +2 hours +Zaire Kinshasa Mbandaka: +1 hours +Zaire Haut Zaire: +2 hours +Zaire Kivu: +2 hours +Zaire Shaba: +2 hours +Zambia: +2 hours +Zimbabwe: +2 hours +All timezone information is non-authoritative... diff --git a/unused/workman.sh b/unused/workman.sh new file mode 100644 index 000000000000..cdf5b7311a8b --- /dev/null +++ b/unused/workman.sh @@ -0,0 +1,29 @@ +#! /bin/sh + +# @(#)workman.sh 8.1 + +# Tell groff not to emit SGR escape sequences (ANSI color escapes). +GROFF_NO_SGR=1 +export GROFF_NO_SGR + +echo ".am TH +.hy 0 +.na +.. +.rm }H +.rm }F" | nroff -man - ${1+"$@"} | perl -ne ' + chomp; + s/.\010//g; + s/\s*$//; + if (/^$/) { + $sawblank = 1; + next; + } else { + if ($sawblank && $didprint) { + print "\n"; + $sawblank = 0; + } + print "$_\n"; + $didprint = 1; + } +' diff --git a/unused/zdump.8.txt b/unused/zdump.8.txt new file mode 100644 index 000000000000..78c647f7636b --- /dev/null +++ b/unused/zdump.8.txt @@ -0,0 +1,43 @@ +NAME + + zdump - time zone dumper + +SYNOPSIS + zdump [ --version ] [ -v ] [ -c [loyear,]hiyear ] [ zonename + ... ] + +DESCRIPTION + Zdump prints the current time in each zonename named on the + command line. + + These options are available: + + --version + Output version information and exit. + + -v For each zonename on the command line, print the time + at the lowest possible time value, 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 + isdst=1 if the given time is Daylight Saving Time or + isdst=0 otherwise. + + -c [loyear,]hiyear + Cut off verbose output near the start of the given + year(s). By default, the program cuts off verbose + output near the starts of the years -500 and 2500. + +LIMITATIONS + The -v option may not be used on systems with floating-point + time_t values that are neither float nor double. + + Time discontinuities are found by sampling the results + returned by localtime at twelve-hour intervals. This works + in all real-world cases; one can construct artificial time + zones for which this fails. + +SEE ALSO + newctime(3), tzfile(5), zic(8) diff --git a/unused/zic.8.txt b/unused/zic.8.txt new file mode 100644 index 000000000000..3607ca768b10 --- /dev/null +++ b/unused/zic.8.txt @@ -0,0 +1,308 @@ +NAME + + zic - time zone compiler + +SYNOPSIS + zic [ --version ] [ -v ] [ -d directory ] [ -l localtime ] [ + -p posixrules ] [ -L leapsecondfilename ] [ -s ] [ -y + command ] [ filename ... ] + +DESCRIPTION + Zic reads text from the file(s) named on the command line + and creates the time conversion information files specified + in this input. If a filename is -, the standard input is + read. + + These options are available: + + --version + Output version information and exit. + + -d directory + Create time conversion information files in the named + directory rather than in the standard directory named + below. + + -l timezone + Use the given time zone as local time. Zic will act as + if the input contained a link line of the form + + Link timezone localtime + + -p timezone + Use the given time zone's rules when handling POSIX- + format time zone environment variables. Zic will act + as if the input contained a link line of the form + + Link timezone posixrules + + -L leapsecondfilename + Read leap second information from the file with the + given name. If this option is not used, no leap second + information appears in output files. + + -v Complain if a year that appears in a data file is + outside the range of years representable by time(2) + values. Also complain if a time of 24:00 (which cannot + be handled by pre-1998 versions of zic) appears in the + input. + + -s Limit time values stored in output files to values that + are the same whether they're taken to be signed or + unsigned. You can use this option to generate SVVS- + compatible files. + + -y command + Use the given command rather than yearistype when + checking year types (see below). + + Input lines are made up of fields. Fields are separated + from one another by any number of white space characters. + Leading and trailing white space on input lines is ignored. + An unquoted sharp character (#) in the input introduces a + comment which extends to the end of the line the sharp + character appears on. White space characters and sharp + characters may be enclosed in double quotes (") if they're + to be used as part of a field. Any line that is blank + (after comment stripping) is ignored. Non-blank lines are + expected to be of one of three types: rule lines, zone + lines, and link lines. + + A rule line has the form + + Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S + + For example: + + Rule US 1967 1973 - Apr lastSun 2:00 1:00 D + + The fields that make up a rule line are: + + NAME Gives the (arbitrary) name of the set of rules this + rule is part of. + + FROM Gives the first year in which the rule applies. Any + integer year can be supplied; the Gregorian calendar + is assumed. The word minimum (or an abbreviation) + means the minimum year representable as an integer. + The word maximum (or an abbreviation) means the + maximum year representable as an integer. Rules can + describe times that are not representable as time + values, with the unrepresentable times ignored; this + allows rules to be portable among hosts with + differing time value types. + + TO Gives the final year in which the rule applies. In + addition to minimum and maximum (as above), the word + only (or an abbreviation) may be used to repeat the + value of the FROM field. + + TYPE Gives the type of year in which the rule applies. + If TYPE is - then the rule applies in all years + between FROM and TO inclusive. If TYPE is something + else, then zic executes the command + yearistype year type + to check the type of a year: an exit status of zero + is taken to mean that the year is of the given type; + an exit status of one is taken to mean that the year + is not of the given type. + + IN Names the month in which the rule takes effect. + Month names may be abbreviated. + + ON Gives the day on which the rule takes effect. + Recognized forms include: + + 5 the fifth of the month + lastSun the last Sunday in the month + lastMon the last Monday in the month + Sun>=8 first Sunday on or after the eighth + Sun<=25 last Sunday on or before the 25th + + Names of days of the week may be abbreviated or + spelled out in full. Note that there must be no + spaces within the ON field. + AT Gives the time of day at which the rule takes + effect. Recognized forms include: + + 2 time in hours + 2:00 time in hours and minutes + 15:00 24-hour format time (for times after noon) + 1:28:14 time in hours, minutes, and seconds + - equivalent to 0 + + where hour 0 is midnight at the start of the day, + and hour 24 is midnight at the end of the day. Any + of these forms may be followed by the letter w if + the given time is local "wall clock" time, s if the + given time is local "standard" time, or u (or g or + z) if the given time is universal time; in the + absence of an indicator, wall clock time is assumed. + + SAVE Gives the amount of time to be added to local + standard time when the rule is in effect. This + field has the same format as the AT field (although, + of course, the w and s suffixes are not used). + + LETTER/S + Gives the "variable part" (for example, the "S" or + "D" in "EST" or "EDT") of time zone abbreviations to + be used when this rule is in effect. If this field + is -, the variable part is null. + + A zone line has the form + + Zone NAME GMTOFF RULES/SAVE FORMAT [UNTILYEAR [MONTH [DAY [TIME]]]] + + For example: + + Zone Australia/Adelaide 9:30 Aus CST 1971 Oct 31 2:00 + + The fields that make up a zone line are: + + NAME The name of the time zone. This is the name used in + creating the time conversion information file for the + zone. + + GMTOFF + The amount of time to add to UTC to get standard time + in this zone. This field has the same format as the + AT and SAVE fields of rule lines; begin the field with + a minus sign if time must be subtracted from UTC. + + RULES/SAVE + The name of the rule(s) that apply in the time zone + or, alternately, an amount of time to add to local + standard time. If this field is - then standard time + always applies in the time zone. + + FORMAT + The format for time zone abbreviations in this time + zone. The pair of characters %s is used to show where + the "variable part" of the time zone abbreviation + goes. Alternately, a slash (/) separates standard and + daylight abbreviations. + + UNTILYEAR [MONTH [DAY [TIME]]] + The time at which the UTC offset or the rule(s) change + for a location. It is specified as a year, a month, a + day, and a time of day. If this is specified, the + time zone information is generated from the given UTC + offset and rule change until the time specified. The + month, day, and time of day have the same format as + the IN, ON, and AT fields of a rule; trailing fields + can be omitted, and default to the earliest possible + value for the missing fields. + + The next line must be a "continuation" line; this has + the same form as a zone line except that the string + "Zone" and the name are omitted, as the continuation + line will place information starting at the time + specified as the "until" information in the previous + line in the file used by the previous line. + Continuation lines may contain "until" information, + just as zone lines do, indicating that the next line + is a further continuation. + + A link line has the form + + Link LINK-FROM LINK-TO + + For example: + + Link Europe/Istanbul Asia/Istanbul + + The LINK-FROM field should appear as the NAME field in some + zone line; the LINK-TO field is used as an alternate name + for that zone. + + Except for continuation lines, lines may appear in any order + in the input. + + Lines in the file that describes leap seconds have the + following form: + + Leap YEAR MONTH DAY HH:MM:SS CORR R/S + + For example: + + Leap 1974 Dec 31 23:59:60 + S + + The YEAR, MONTH, DAY, and HH:MM:SS fields tell when the leap + second happened. The CORR field should be "+" if a second + was added or "-" if a second was skipped. The R/S field + should be (an abbreviation of) "Stationary" if the leap + second time given by the other fields should be interpreted + as UTC or (an abbreviation of) "Rolling" if the leap second + time given by the other fields should be interpreted as + local wall clock time. + +EXTENDED EXAMPLE + Here is an extended example of zic input, intended to + illustrate many of its features. + + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S + Rule Swiss 1940 only - Nov 2 0:00 1:00 S + Rule Swiss 1940 only - Dec 31 0:00 0 - + Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 S + Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0 + Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S + Rule EU 1977 only - Sep lastSun 1:00u 0 - + Rule EU 1978 only - Oct 1 1:00u 0 - + Rule EU 1979 1995 - Sep lastSun 1:00u 0 - + Rule EU 1981 max - Mar lastSun 1:00u 1:00 S + Rule EU 1996 max - Oct lastSun 1:00u 0 - + + # Zone NAME GMTOFF RULES FORMAT UNTIL + Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12 + 0:29:44 - BMT 1894 Jun + 1:00 Swiss CE%sT 1981 + 1:00 EU CE%sT + + Link Europe/Zurich Switzerland + + In this example, the zone is named Europe/Zurich but it has + an alias as Switzerland. Zurich was 34 minutes and 8 + seconds west of GMT until 1848-09-12 at 00:00, when the + offset changed to 29 minutes and 44 seconds. After + 1894-06-01 at 00:00 Swiss daylight saving rules (defined + with lines beginning with "Rule Swiss") apply, and the GMT + offset became one hour. From 1981 to the present, EU + daylight saving rules have applied, and the UTC offset has + remained at one hour. + + In 1940, daylight saving time applied from November 2 at + 00:00 to December 31 at 00:00. In 1941 and 1942, daylight + saving time applied from the first Sunday in May at 02:00 to + the first Sunday in October at 00:00. The pre-1981 EU + daylight-saving rules have no effect here, but are included + for completeness. Since 1981, daylight saving has begun on + the last Sunday in March at 01:00 UTC. Until 1995 it ended + the last Sunday in September at 01:00 UTC, but this changed + to the last Sunday in October starting in 1996. + + For purposes of display, "LMT" and "BMT" were initially + used, respectively. Since Swiss rules and later EU rules + were applied, the display name for the timezone has been CET + for standard time and CEST for daylight saving time. + +NOTES + For areas with more than two types of local time, you may + need to use local standard time in the AT field of the + earliest transition time's rule to ensure that the earliest + transition time recorded in the compiled file is correct. + + If, for a particular zone, a clock advance caused by the + start of daylight saving coincides with and is equal to a + clock retreat caused by a change in UTC offset, zic produces + a single transition to daylight saving at the new UTC offset + (without any change in wall clock time). To get separate + transitions use multiple zone continuation lines specifying + transition instants using universal time. + +FILE + /usr/local/etc/zoneinfo standard directory used for + created files + +SEE ALSO + newctime(3), tzfile(5), zdump(8) diff --git a/unused/zoneinfo2tdf.pl b/unused/zoneinfo2tdf.pl new file mode 100755 index 000000000000..f34ca3e99c31 --- /dev/null +++ b/unused/zoneinfo2tdf.pl @@ -0,0 +1,54 @@ +#! /usr/bin/perl -w + +# @(#)zoneinfo2tdf.pl 8.2 + +# Courtesy Ken Pizzini. + +use strict; + +#This file released to the public domain. + +#Note: error checking is poor --- only trust the output if the input +#has been checked by zic. + +my $contZone = ''; +while (<>) { + my $origline = $_; + my @fields = (); + while (s/^\s*((?:"[^"]*"|[^\s#])+)//) { + push @fields, $1; + } + next unless @fields; + + my $type = lc($fields[0]); + if ($contZone) { + @fields >= 3 or warn "bad continuation line"; + unshift @fields, '+', $contZone; + $type = 'zone'; + } + + $contZone = ''; + if ($type eq 'zone') { + # Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] + my $nfields = @fields; + $nfields >= 5 or warn "bad zone line"; + if ($nfields > 6) { + #this splice is optional, depending on one's preference + #(one big date-time field, or componentized date and time): + splice(@fields, 5, $nfields-5, "@fields[5..$nfields-1]"); + } + $contZone = $fields[1] if @fields > 5; + } elsif ($type eq 'rule') { + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S + @fields == 10 or warn "bad rule line"; + } elsif ($type eq 'link') { + # Link LINK-FROM LINK-TO + @fields == 3 or warn "bad link line"; + } elsif ($type eq 'leap') { + # Leap YEAR MONTH DAY HH:MM:SS CORR R/S + @fields == 7 or warn "bad leap line"; + } else { + warn "Fubar at input line $.: $origline"; + } + print join("\t", @fields), "\n"; +} diff --git a/zic/Music b/zic/Music deleted file mode 100644 index 9fb0cecacca8..000000000000 --- a/zic/Music +++ /dev/null @@ -1,81 +0,0 @@ -@(#)Music 7.4 - -Data on recordings of "Save That Time," Russ Long, Serrob Publishing, BMI: --------------------------------------------------------------------------- -Artist: Karrin Allyson -CD: I Didn't Know About You -Copyright Date: 1993 -Label: Concord Jazz, Inc. -ID: CCD-4543 -Track Time: 3:44 -Personnel: Karrin Allyson, vocal - Russ Long, piano - Gerald Spaits, bass - Todd Strait, drums -Notes: CD notes "additional lyric by Karrin Allyson; - arranged by Russ Long and Karrin Allyson" -Rating: 1 star --------------------------------------------------------------------------- -Artist: Kevin Mahogany -CD: Double Rainbow -Copyright Date: 1993 -Label: Enja Records -ID: ENJ-7097 2 -Track Time: 6:27 -Personnel: Kevin Mahogany, vocal - Kenny Barron, piano - Ray Drummond, bss - Ralph Moore, tenor saxophone - Lewis Nash, drums -Rating: 1.5 stars --------------------------------------------------------------------------- -Artist: Joe Williams -CD: Here's to Life -Copyright Date: 1994 -Label: Telarc International Corporation -ID: CD-83357 -Track Time: 3:58 -Personnel: Joe Williams, vocal - The Robert Farnon [39 piece] Orchestra -Rating: black dot --------------------------------------------------------------------------- -Artist: Charles Fambrough -CD: Keeper of the Spirit -Copyright Date: 1995 -Label: AudioQuest Music -ID: AQ-CD1033 -Track Time: 7:07 -Personnel: Charles Fambrough, bass - Joel Levine, tenor recorder - Edward Simon, piano - Lenny White, drums - Marion Simon, percussion -Rating: 2 stars -========================================================================== -Also of note: -Artist: Milt Hinton -CD: Old Man Time -Date: 1993 -Label: Chiaroscuro -ID: CR(D) 310 -Total Time: 149:38 (two CDs) -Personnel: Milt Hinton, bass - Doc Cheatham, Dizzy Gillespie, Clark Terry, trumpet - Al Grey, trombone - Eddier Barefield, Joe Camel (Flip Phillips), Buddy Tate, - clarinet and saxophone - John Bunch, Red Richards, Norman Simmons, Derek Smith, - Ralph Sutton, piano - Danny Barker, Al Casey, guitar - Gus Johnson, Gerryck King, Bob Rosengarden, Jackie Williams, - drums - Lionel Hampton, vibraphone - Cab Calloway, Joe Williams, vocal - Buck Clayton, arrangements -Notes: tunes include Old Man Time, Time After Time, - Sometimes I'm Happy, - A Hot Time in the Old Town Tonight, - Four or Five Times, Now's the Time, - Time on My Hands, This Time It's Us, - and Good Time Charlie -Rating: 3 stars diff --git a/zic/README b/zic/README index 985a5118468f..c0cc92853d0c 100644 --- a/zic/README +++ b/zic/README @@ -1,4 +1,4 @@ -@(#)README 7.11 +@(#)README 8.2 "What time is it?" -- Richard Deacon as The King "Any time you want it to be." -- Frank Baxter as The Scientist @@ -52,8 +52,10 @@ substituting your desired installation directory for "$HOME/tzdir": To use the new functions, use a "-ltz" option when compiling or linking. -Historical local time information has been included here not because it -is particularly useful, but rather to: +Historical local time information has been included here to: + +* provide a compendium of data about the history of civil time + that is useful even if the data are not 100% accurate; * give an idea of the variety of local time rules that have existed in the past and thus an idea of the variety that may be @@ -63,7 +65,9 @@ is particularly useful, but rather to: system. The information in the time zone data files is by no means authoritative; -if you know that the rules are different from those in a file, by all means +the files currently do not even attempt to cover all time stamps before +1970, and there are undoubtedly errors even for time stamps since 1970. +If you know that the rules are different from those in a file, by all means feel free to change file (and please send the changed version to tz@elsie.nci.nih.gov for use in the future). Europeans take note! diff --git a/zic/Theory b/zic/Theory index cbf53b9e7d73..b842fb4b7532 100644 --- a/zic/Theory +++ b/zic/Theory @@ -1,4 +1,4 @@ -@(#)Theory 7.15 +@(#)Theory 8.2 ----- Outline ----- @@ -12,26 +12,27 @@ ----- Time and date functions ----- -These time and date functions are upwards compatible with POSIX.1, +These time and date functions are upwards compatible with POSIX, an international standard for UNIX-like systems. -As of this writing, the current edition of POSIX.1 is: +As of this writing, the current edition of POSIX is: - Information technology --Portable Operating System Interface (POSIX (R)) - -- Part 1: System Application Program Interface (API) [C Language] - ISO/IEC 9945-1:1996 - ANSI/IEEE Std 1003.1, 1996 Edition - 1996-07-12 + Standard for Information technology + -- Portable Operating System Interface (POSIX (R)) + -- System Interfaces + IEEE Std 1003.1, 2004 Edition + + -POSIX.1 has the following properties and limitations. +POSIX has the following properties and limitations. -* In POSIX.1, time display in a process is controlled by the - environment variable TZ. Unfortunately, the POSIX.1 TZ string takes +* In POSIX, time display in a process is controlled by the + environment variable TZ. Unfortunately, the POSIX TZ string takes a form that is hard to describe and is error-prone in practice. - Also, POSIX.1 TZ strings can't deal with other (for example, Israeli) + Also, POSIX TZ strings can't deal with other (for example, Israeli) daylight saving time rules, or situations where more than two time zone abbreviations are used in an area. - The POSIX.1 TZ string takes the following form: + The POSIX TZ string takes the following form: stdoffset[dst[offset],date[/time],date[/time]] @@ -40,6 +41,9 @@ POSIX.1 has the following properties and limitations. std and dst are 3 or more characters specifying the standard and daylight saving time (DST) zone names. + Starting with POSIX.1-2001, std and dst may also be + in a quoted form like ""; this allows + "+" and "-" in the names. offset is of the form `[-]hh:[mm[:ss]]' and specifies the offset west of UTC. The default DST offset is one hour @@ -62,14 +66,25 @@ POSIX.1 has the following properties and limitations. and `5' stands for the last week in which day d appears (which may be either the 4th or 5th week). -* In POSIX.1, when a TZ value like "EST5EDT" is parsed, - typically the current US DST rules are used, + Here is an example POSIX TZ string, for US Pacific time using rules + appropriate from 1987 through 2006: + + TZ='PST8PDT,M4.1.0/02:00,M10.5.0/02:00' + + This POSIX TZ string is hard to remember, and mishandles time stamps + before 1987 and after 2006. With this package you can use this + instead: + + TZ='America/Los_Angeles' + +* POSIX does not define the exact meaning of TZ values like "EST5EDT". + Typically the current US DST rules are used to interpret such values, but this means that the US DST rules are compiled into each program that does time conversion. This means that when US time conversion rules change (as in the United States in 1987), all programs that do time conversion must be recompiled to ensure proper results. -* In POSIX.1, there's no tamper-proof way for a process to learn the +* In POSIX, there's no tamper-proof way for a process to learn the system's best idea of local wall clock. (This is important for applications that an administrator wants used only at certain times-- without regard to whether the user has fiddled the "TZ" environment @@ -78,9 +93,9 @@ POSIX.1 has the following properties and limitations. daylight saving time shifts--as might be required to limit phone calls to off-peak hours.) -* POSIX.1 requires that systems ignore leap seconds. +* POSIX requires that systems ignore leap seconds. -These are the extensions that have been made to the POSIX.1 functions: +These are the extensions that have been made to the POSIX functions: * The "TZ" environment variable is used in generating the name of a file from which time zone information is read (or is interpreted a la @@ -108,7 +123,7 @@ These are the extensions that have been made to the POSIX.1 functions: * To handle places where more than two time zone abbreviations are used, the functions "localtime" and "gmtime" set tzname[tmp->tm_isdst] (where "tmp" is the value the function returns) to the time zone - abbreviation to be used. This differs from POSIX.1, where the elements + abbreviation to be used. This differs from POSIX, where the elements of tzname are only changed as a result of calls to tzset. * Since the "TZ" environment variable can now be used to control time @@ -131,8 +146,7 @@ These are the extensions that have been made to the POSIX.1 functions: environment variable; portable applications should not, however, rely on this behavior since it's not the way SVR2 systems behave.) -* These functions can account for leap seconds, thanks to Bradley White - (bww@k.cs.cmu.edu). +* These functions can account for leap seconds, thanks to Bradley White. Points of interest to folks with other systems: @@ -173,9 +187,9 @@ Hewlett Packard, offer a wider selection of functions that provide capabilities beyond those provided here. The absence of such functions from this package is not meant to discourage the development, standardization, or use of such functions. Rather, their absence reflects the decision to make this package -contain valid extensions to POSIX.1, to ensure its broad -acceptability. If more powerful time conversion functions can be standardized, -so much the better. +contain valid extensions to POSIX, to ensure its broad acceptability. If +more powerful time conversion functions can be standardized, so much the +better. ----- Names of time zone rule files ----- @@ -228,6 +242,8 @@ in decreasing order of importance: Include at least one location per time zone rule set per country. One such location is enough. Use ISO 3166 (see the file iso3166.tab) to help decide whether something is a country. + However, uninhabited ISO 3166 regions like Bouvet Island + do not need locations, since local time is not defined there. If all the clocks in a country's region have agreed since 1970, don't bother to include more than one location even if subregions' clocks disagreed before 1970. @@ -263,7 +279,8 @@ in decreasing order of importance: If a name is changed, put its old spelling in the `backward' file. The file `zone.tab' lists the geographical locations used to name -time zone rule files. +time zone rule files. It is intended to be an exhaustive list +of canonical names for geographic regions. Older versions of this package used a different naming scheme, and these older names are still supported. @@ -277,7 +294,7 @@ and `Factory' (see the file `factory'). ----- Time zone abbreviations ----- When this package is installed, it generates time zone abbreviations -like `EST' to be compatible with human tradition and POSIX.1. +like `EST' to be compatible with human tradition and POSIX. Here are the general rules used for choosing time zone abbreviations, in decreasing order of importance: @@ -292,17 +309,16 @@ in decreasing order of importance: preferred "ChST", so the rule has been relaxed. This rule guarantees that all abbreviations could have - been specified by a POSIX.1 TZ string. POSIX.1 + been specified by a POSIX TZ string. POSIX requires at least three characters for an - abbreviation. POSIX.1-1996 says that an abbreviation + abbreviation. POSIX through 2000 says that an abbreviation cannot start with ':', and cannot contain ',', '-', - '+', NUL, or a digit. Draft 7 of POSIX 1003.1-200x - changes this rule to say that an abbreviation can - contain only '-', '+', and alphanumeric characters in - the current locale. To be portable to both sets of + '+', NUL, or a digit. POSIX from 2001 on changes this + rule to say that an abbreviation can contain only '-', '+', + and alphanumeric characters from the portable character set + in the current locale. To be portable to both sets of rules, an abbreviation must therefore use only ASCII - letters, as these are the only letters that are - alphabetic in all locales. + letters. Use abbreviations that are in common use among English-speakers, e.g. `EST' for Eastern Standard Time in North America. @@ -328,8 +344,9 @@ in decreasing order of importance: and then append `T', `ST', etc. as before; e.g. `VLAST' for VLAdivostok Summer Time. - Use "zzz" for locations while uninhabited. The mnemonic is that - these locations are, in some sense, asleep. + Use UTC (with time zone abbreviation "zzz") for locations while + uninhabited. The "zzz" mnemonic is that these locations are, + in some sense, asleep. Application writers should note that these abbreviations are ambiguous in practice: e.g. `EST' has a different meaning in Australia than @@ -343,10 +360,10 @@ abbreviations like `EST'; this avoids the ambiguity. Calendrical issues are a bit out of scope for a time zone database, but they indicate the sort of problems that we would run into if we extended the time zone database further into the past. An excellent -resource in this area is Nachum Dershowitz and Edward M. Reingold, - -Calendrical Calculations -, Cambridge University Press (1997). Other information and +resource in this area is Edward M. Reingold and Nachum Dershowitz, + +Calendrical Calculations: The Millennium Edition +, Cambridge University Press (2001). Other information and sources are given below. They sometimes disagree. @@ -359,7 +376,7 @@ and (in Paris only) 1871-05-06 through 1871-05-23. Russia -From Chris Carrier <72157.3334@CompuServe.COM> (1996-12-02): +From Chris Carrier (1996-12-02): On 1929-10-01 the Soviet Union instituted an ``Eternal Calendar'' with 30-day months plus 5 holidays, with a 5-day week. On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the @@ -374,7 +391,7 @@ by Frank Parise (1982, Facts on File, ISBN 0-8719-6467-8), page 377. But: From: Petteri Sulonen (via Usenet) Date: 14 Jan 1999 00:00:00 GMT -Message-ID: +... If your source is correct, how come documents between 1929 -- 1940 were still dated using the conventional, Gregorian calendar? @@ -387,7 +404,7 @@ Executive Committee of the Supreme Soviet, if you like. Sweden (and Finland) -From: msb@sq.com (Mark Brader) +From: Mark Brader Subject: Re: Gregorian reform -- a part of locale? @@ -415,11 +432,11 @@ kalendervasen" by Lars-Olof Lode'n (no date was given).) Grotefend's data -From: "Michael Palmer" [with one obvious typo fixed] +From: "Michael Palmer" [with one obvious typo fixed] Subject: Re: Gregorian Calendar (was Re: Another FHC related question Newsgroups: soc.genealogy.german Date: Tue, 9 Feb 1999 02:32:48 -800 -Message-ID: <199902091032.CAA09644@netcom10.netcom.com> +... The following is a(n incomplete) listing, arranged chronologically, of European states, with the date they converted from the Julian to the @@ -546,7 +563,7 @@ Sources: Michael Allison and Robert Schmunk, "Technical Notes on Mars Solar Time as Adopted by the Mars24 Sunclock" - (2004-03-15). + (2004-07-30). Jia-Rui Chong, "Workdays Fit for a Martian", Los Angeles Times (2004-01-14), pp A1, A20-A21. diff --git a/zic/ialloc.c b/zic/ialloc.c index 8a0c70157890..1fc2035f4529 100644 --- a/zic/ialloc.c +++ b/zic/ialloc.c @@ -1,6 +1,11 @@ +/* +** This file is in the public domain, so clarified as of +** 2006-07-17 by Arthur David Olson. +*/ + #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)ialloc.c 8.29"; +static char elsieid[] = "@(#)ialloc.c 8.30"; #endif /* !defined NOID */ #endif /* !defined lint */ diff --git a/zic/private.h b/zic/private.h index c8f45486837f..008d468ac787 100644 --- a/zic/private.h +++ b/zic/private.h @@ -4,7 +4,7 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. */ /* @@ -21,10 +21,12 @@ #ifndef lint #ifndef NOID -static char privatehid[] = "@(#)private.h 7.53"; +static char privatehid[] = "@(#)private.h 8.6"; #endif /* !defined NOID */ #endif /* !defined lint */ +#define GRANDPARENTED "Local time zone must be set--see zic manual page" + /* ** Defaults for preprocessor symbols. ** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'. @@ -46,10 +48,6 @@ static char privatehid[] = "@(#)private.h 7.53"; #define HAVE_SETTIMEOFDAY 3 #endif /* !defined HAVE_SETTIMEOFDAY */ -#ifndef HAVE_STRERROR -#define HAVE_STRERROR 1 -#endif /* !defined HAVE_STRERROR */ - #ifndef HAVE_SYMLINK #define HAVE_SYMLINK 1 #endif /* !defined HAVE_SYMLINK */ @@ -87,17 +85,17 @@ static char privatehid[] = "@(#)private.h 7.53"; #include "stdio.h" #include "errno.h" #include "string.h" -#include "limits.h" /* for CHAR_BIT */ +#include "limits.h" /* for CHAR_BIT et al. */ #include "time.h" #include "stdlib.h" -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #include "libintl.h" -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ -#if HAVE_SYS_WAIT_H - 0 +#if HAVE_SYS_WAIT_H #include /* for WIFEXITED and WEXITSTATUS */ -#endif /* HAVE_SYS_WAIT_H - 0 */ +#endif /* HAVE_SYS_WAIT_H */ #ifndef WIFEXITED #define WIFEXITED(status) (((status) & 0xff) == 0) @@ -106,106 +104,82 @@ static char privatehid[] = "@(#)private.h 7.53"; #define WEXITSTATUS(status) (((status) >> 8) & 0xff) #endif /* !defined WEXITSTATUS */ -#if HAVE_UNISTD_H - 0 -#include "unistd.h" /* for F_OK and R_OK */ -#endif /* HAVE_UNISTD_H - 0 */ +#if HAVE_UNISTD_H +#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */ +#endif /* HAVE_UNISTD_H */ -#if !(HAVE_UNISTD_H - 0) #ifndef F_OK #define F_OK 0 #endif /* !defined F_OK */ #ifndef R_OK #define R_OK 4 #endif /* !defined R_OK */ -#endif /* !(HAVE_UNISTD_H - 0) */ -/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ +/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ #define is_digit(c) ((unsigned)(c) - '0' <= 9) +/* +** Define HAVE_STDINT_H's default value here, rather than at the +** start, since __GLIBC__'s value depends on previously-included +** files. +** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.) +*/ +#ifndef HAVE_STDINT_H +#define HAVE_STDINT_H \ + (199901 <= __STDC_VERSION__ || \ + 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__))) +#endif /* !defined HAVE_STDINT_H */ + +#if HAVE_STDINT_H +#include "stdint.h" +#endif /* !HAVE_STDINT_H */ + +#ifndef INT_FAST64_MAX +/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */ +#if defined LLONG_MAX || defined __LONG_LONG_MAX__ +typedef long long int_fast64_t; +#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#if (LONG_MAX >> 31) < 0xffffffff +Please use a compiler that supports a 64-bit integer type (or wider); +you may need to compile with "-DHAVE_STDINT_H". +#endif /* (LONG_MAX >> 31) < 0xffffffff */ +typedef long int_fast64_t; +#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#endif /* !defined INT_FAST64_MAX */ + +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif /* !defined INT32_MAX */ +#ifndef INT32_MIN +#define INT32_MIN (-1 - INT32_MAX) +#endif /* !defined INT32_MIN */ + /* ** Workarounds for compilers/systems. */ /* -** SunOS 4.1.1 cc lacks prototypes. -*/ - -#ifndef P -#ifdef __STDC__ -#define P(x) x -#endif /* defined __STDC__ */ -#ifndef __STDC__ -#define P(x) () -#endif /* !defined __STDC__ */ -#endif /* !defined P */ - -/* -** SunOS 4.1.1 headers lack EXIT_SUCCESS. -*/ - -#ifndef EXIT_SUCCESS -#define EXIT_SUCCESS 0 -#endif /* !defined EXIT_SUCCESS */ - -/* -** SunOS 4.1.1 headers lack EXIT_FAILURE. -*/ - -#ifndef EXIT_FAILURE -#define EXIT_FAILURE 1 -#endif /* !defined EXIT_FAILURE */ - -/* -** SunOS 4.1.1 headers lack FILENAME_MAX. -*/ - -#ifndef FILENAME_MAX - -#ifndef MAXPATHLEN -#ifdef unix -#include "sys/param.h" -#endif /* defined unix */ -#endif /* !defined MAXPATHLEN */ - -#ifdef MAXPATHLEN -#define FILENAME_MAX MAXPATHLEN -#endif /* defined MAXPATHLEN */ -#ifndef MAXPATHLEN -#define FILENAME_MAX 1024 /* Pure guesswork */ -#endif /* !defined MAXPATHLEN */ - -#endif /* !defined FILENAME_MAX */ - -/* -** SunOS 4.1.1 libraries lack remove. -*/ - -#ifndef remove -extern int unlink P((const char * filename)); -#define remove unlink -#endif /* !defined remove */ - -/* -** Some ancient errno.h implementations don't declare errno. -** But some newer errno.h implementations define it as a macro. +** Some time.h implementations don't declare asctime_r. +** Others might define it as a macro. ** Fix the former without affecting the latter. */ -#ifndef errno -extern int errno; -#endif /* !defined errno */ + +#ifndef asctime_r +extern char * asctime_r(struct tm const *, char *); +#endif /* ** Private function declarations. */ -char * icalloc P((int nelem, int elsize)); -char * icatalloc P((char * old, const char * new)); -char * icpyalloc P((const char * string)); -char * imalloc P((int n)); -void * irealloc P((void * pointer, int size)); -void icfree P((char * pointer)); -void ifree P((char * pointer)); -char * scheck P((const char *string, const char *format)); +char * icalloc(int nelem, int elsize); +char * icatalloc(char * old, const char * new); +char * icpyalloc(const char * string); +char * imalloc(int n); +void * irealloc(void * pointer, int size); +void icfree(char * pointer); +void ifree(char * pointer); +const char * scheck(const char * string, const char * format); /* ** Finally, some convenience items. @@ -227,6 +201,15 @@ char * scheck P((const char *string, const char *format)); #define TYPE_SIGNED(type) (((type) -1) < 0) #endif /* !defined TYPE_SIGNED */ +/* +** Since the definition of TYPE_INTEGRAL contains floating point numbers, +** it cannot be used in preprocessor directives. +*/ + +#ifndef TYPE_INTEGRAL +#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5) +#endif /* !defined TYPE_INTEGRAL */ + #ifndef INT_STRLEN_MAXIMUM /* ** 302 / 1000 is log10(2.0) rounded up. @@ -235,7 +218,8 @@ char * scheck P((const char *string, const char *format)); ** add one more for a minus sign if the type is signed. */ #define INT_STRLEN_MAXIMUM(type) \ - ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type)) + ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \ + 1 + TYPE_SIGNED(type)) #endif /* !defined INT_STRLEN_MAXIMUM */ /* @@ -269,11 +253,11 @@ char * scheck P((const char *string, const char *format)); */ #ifndef _ -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #define _(msgid) gettext(msgid) -#else /* !(HAVE_GETTEXT - 0) */ +#else /* !HAVE_GETTEXT */ #define _(msgid) msgid -#endif /* !(HAVE_GETTEXT - 0) */ +#endif /* !HAVE_GETTEXT */ #endif /* !defined _ */ #ifndef TZ_DOMAIN @@ -283,10 +267,30 @@ char * scheck P((const char *string, const char *format)); #if HAVE_INCOMPATIBLE_CTIME_R #undef asctime_r #undef ctime_r -char *asctime_r P((struct tm const *, char *)); -char *ctime_r P((time_t const *, char *)); +char *asctime_r(struct tm const *, char *); +char *ctime_r(time_t const *, char *); #endif /* HAVE_INCOMPATIBLE_CTIME_R */ +#ifndef YEARSPERREPEAT +#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ +#endif /* !defined YEARSPERREPEAT */ + +/* +** The Gregorian year averages 365.2425 days, which is 31556952 seconds. +*/ + +#ifndef AVGSECSPERYEAR +#define AVGSECSPERYEAR 31556952L +#endif /* !defined AVGSECSPERYEAR */ + +#ifndef SECSPERREPEAT +#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR) +#endif /* !defined SECSPERREPEAT */ + +#ifndef SECSPERREPEAT_BITS +#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */ +#endif /* !defined SECSPERREPEAT_BITS */ + /* ** UNIX was a registered trademark of The Open Group in 2003. */ diff --git a/zic/scheck.c b/zic/scheck.c index 39feeba70117..74d9b07c149b 100644 --- a/zic/scheck.c +++ b/zic/scheck.c @@ -1,6 +1,11 @@ +/* +** This file is in the public domain, so clarified as of +** 2006-07-17 by Arthur David Olson. +*/ + #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)scheck.c 8.15"; +static char elsieid[] = "@(#)scheck.c 8.19"; #endif /* !defined lint */ #endif /* !defined NOID */ @@ -8,7 +13,7 @@ static char elsieid[] = "@(#)scheck.c 8.15"; #include "private.h" -char * +const char * scheck(string, format) const char * const string; const char * const format; @@ -17,11 +22,10 @@ const char * const format; register const char * fp; register char * tp; register int c; - register char * result; + register const char * result; char dummy; - static char nada; - result = &nada; + result = ""; if (string == NULL || format == NULL) return result; fbuf = imalloc((int) (2 * strlen(format) + 4)); diff --git a/zic/tz-link.htm b/zic/tz-link.htm deleted file mode 100644 index 0e6307300709..000000000000 --- a/zic/tz-link.htm +++ /dev/null @@ -1,443 +0,0 @@ - - - - -Sources for Time Zone and Daylight Saving Time Data - - - - - - - - - - -

    Sources for Time Zone and Daylight Saving Time Data

    -
    -@(#)tz-link.htm 7.42 -
    -

    -Please send corrections to this web page to the -time zone mailing list. -

    -

    The tz database

    -

    -The public-domain time zone database contains code and data -that represent the history of local time -for many representative locations around the globe. -It is updated periodically to reflect changes made by political bodies -to UTC offsets and daylight-saving rules. -This database (often called tz or zoneinfo) -is used by several implementations, -including -the GNU C Library used in -GNU/Linux, -FreeBSD, -NetBSD, -OpenBSD, -Cygwin, -DJGPP, -HP-UX, -IRIX, -Mac OS X, -OpenVMS, -Solaris, -Tru64, and -UnixWare.

    -

    -Each location in the database represents a national region where all -clocks keeping local time have agreed since 1970. -Locations are identified by continent or ocean and then by the name of -the location, which is typically the largest city within the region. -For example, America/New_York -represents most of the US eastern time zone; -America/Indianapolis represents most of Indiana, which -uses eastern time without daylight saving time (DST); -America/Detroit represents most of Michigan, which uses -eastern time but with different DST rules in 1975; -and other entries represent smaller regions like Starke County, -Kentucky, which switched from central to eastern time in 1991. -To use the database, set the TZ environment variable to -the location's full name, e.g., TZ="America/New_York".

    -

    -In the tz database's -FTP distribution, -the code is in the file tzcodeC.tar.gz, -where C is the code's version; -similarly, the data are in tzdataD.tar.gz, -where D is the data's version. -The following shell commands download -these files to a GNU/Linux or similar host; see the downloaded -README file for what to do next.

    -
    wget 'ftp://elsie.nci.nih.gov/pub/tz*.tar.gz'
    -gzip -dc tzcode*.tar.gz | tar -xf -
    -gzip -dc tzdata*.tar.gz | tar -xf -
    -
    -

    -The code lets you compile the tz source files into -machine-readable binary files, one for each location. It also lets -you read a tz binary file and interpret time stamps for that -location.

    -

    -The data are by no means authoritative. If you find errors, please -send changes to the time zone -mailing list. You can also subscribe to the -mailing list, retrieve the archive of old -messages (in gzip compressed format), or retrieve archived older versions of code -and data.

    -

    -The Web has several other sources for time zone and daylight saving time data. -Here are some recent links that may be of interest. -

    -

    Web pages using recent versions of the tz database

    - -

    Other time zone database formats

    - -

    Other tz compilers

    - -

    Other tz binary file readers

    - -

    Other tz-based time zone conversion software

    - -

    Other time zone databases

    - -

    Maps

    - -

    Time zone boundaries

    - -

    Civil time concepts and history

    - -

    National histories of legal time

    -
    -
    Australia
    -
    The Community Relations Division of the New South Wales (NSW) -Attorney General's Department maintains a history of -daylight saving in NSW.
    -
    Austria
    -
    The Federal Office of Metrology and Surveying publishes a -table of daylight saving time in Austria (in German).
    -
    Belgium
    -
    The Royal Observatory of Belgium maintains a table of time in Belgium (in Dutch).
    -
    Brazil
    -
    The Time Service Department of the National Observatory -records Brazil's daylight saving time decrees (in -Portuguese).
    -
    Canada
    -
    The Institute for National Measurement Standards publishes current -and some older information about Time -Zones and Daylight Saving Time.
    -
    Chile
    -
    WebExhibits publishes a history of official time (in Spanish) originally -written by the Chilean Hydrographic and Oceanographic Service.
    -
    Germany
    -
    The National Institute for Science and Technology maintains the Realisation of -Legal Time in Germany.
    -
    Israel
    -
    The Interior Ministry periodically issues announcements (in Hebrew).
    -
    Mexico
    -
    The Investigation and Analysis Service of the Mexican Library of -Congress has published a history of Mexican local time (in Spanish).
    -
    Malaysia
    -
    See Singapore below.
    -
    Netherlands
    -
    Legal time in the Netherlands (in Dutch) -covers the history of local time in the Netherlands from ancient times.
    -
    New Zealand
    -
    The Department of Internal Affairs maintains a brief history about -daylight saving. The privately-maintained Time Changes in -New Zealand has more details.
    -
    Singapore
    -
    Why -is Singapore in the "Wrong" Time Zone? details the -history of legal time in Singapore and Malaysia.
    -
    United Kingdom
    -
    History of -legal time in Britain discusses in detail the country -with perhaps the best-documented history of clock adjustments. -The National Physical Laboratory also maintains an archive -of summer time dates.
    -
    -

    Precision timekeeping

    - -

    Time notation

    -
      -
    • -A Summary of -the International Standard Date and Time Notation is a good -summary of ISO -8601:1988 - Data elements and interchange formats - Information interchange -- Representation of dates and times (which has been superseded by -ISO 8601:2000).
    • -
    • -Section 3.3 of Internet RFC 2822 -specifies the time notation used in email and HTTP headers.
    • -
    • -Internet RFC -3339 specifies an ISO 8601 profile for use in new Internet -protocols.
    • -
    • -The -Best of Dates, the Worst of Dates covers many problems encountered -by software developers when handling dates and time stamps.
    • -
    • -Alphabetic time zone abbreviations should not be used as unique -identifiers for UTC offsets as they are ambiguous in practice. For -example, "EST" denotes 5 hours behind UTC in English-speaking North -America, but it denotes 10 or 11 hours ahead of UTC in Australia; -and French-speaking North Americans prefer "HNE" to "EST". For -compatibility with POSIX the -tz database contains English abbreviations for all time -stamps but in many cases these are merely inventions of the database -maintainers.
    • -
    -

    Related indexes

    - - - diff --git a/zic/zdump.8 b/zic/zdump.8 index dff68c2d8d88..67cbaead4b55 100644 --- a/zic/zdump.8 +++ b/zic/zdump.8 @@ -10,7 +10,7 @@ zdump \- time zone dumper .B \-v ] [ .B \-c -cutoffyear ] [ zonename ... ] +[loyear,]hiyear ] [ zonename ... ] .SH DESCRIPTION .I Zdump prints the current time in each @@ -38,8 +38,20 @@ if the given time is Daylight Saving Time or .B isdst=0 otherwise. .TP -.BI "\-c " cutoffyear -Cut off the verbose output near the start of the given year. +.BI "\-c " [loyear,]hiyear +Cut off verbose output near the start of the given year(s). +By default, +the program cuts off verbose output near the starts of the years -500 and 2500. +.SH LIMITATIONS +The +.B \-v +option may not be used on systems with floating-point time_t values +that are neither float nor double. +.PP +Time discontinuities are found by sampling the results returned by localtime +at twelve-hour intervals. +This works in all real-world cases; +one can construct artificial time zones for which this fails. .SH "SEE ALSO" newctime(3), tzfile(5), zic(8) -.\" @(#)zdump.8 7.4 +.\" @(#)zdump.8 8.1 diff --git a/zic/zdump.c b/zic/zdump.c index a34caddbdf62..085b33e23d4e 100644 --- a/zic/zdump.c +++ b/zic/zdump.c @@ -1,4 +1,4 @@ -static char elsieid[] = "@(#)zdump.c 7.31"; +static char elsieid[] = "@(#)zdump.c 8.8"; /* ** This code has been made independent of the rest of the time @@ -11,6 +11,19 @@ static char elsieid[] = "@(#)zdump.c 7.31"; #include "sys/types.h" /* for time_t */ #include "time.h" /* for struct tm */ #include "stdlib.h" /* for exit, malloc, atoi */ +#include "float.h" /* for FLT_MAX and DBL_MAX */ +#include "ctype.h" /* for isalpha et al. */ +#ifndef isascii +#define isascii(x) 1 +#endif /* !defined isascii */ + +#ifndef ZDUMP_LO_YEAR +#define ZDUMP_LO_YEAR (-500) +#endif /* !defined ZDUMP_LO_YEAR */ + +#ifndef ZDUMP_HI_YEAR +#define ZDUMP_HI_YEAR 2500 +#endif /* !defined ZDUMP_HI_YEAR */ #ifndef MAX_STRING_LENGTH #define MAX_STRING_LENGTH 1024 @@ -61,19 +74,32 @@ static char elsieid[] = "@(#)zdump.c 7.31"; #endif /* !defined DAYSPERNYEAR */ #ifndef isleap -#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) #endif /* !defined isleap */ -#if HAVE_GETTEXT - 0 +#ifndef isleap_sum +/* +** See tzfile.h for details on isleap_sum. +*/ +#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) +#endif /* !defined isleap_sum */ + +#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) +#define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR) +#define SECSPERLYEAR (SECSPERNYEAR + SECSPERDAY) + +#ifndef HAVE_GETTEXT +#define HAVE_GETTEXT 0 +#endif +#if HAVE_GETTEXT #include "locale.h" /* for setlocale */ #include "libintl.h" -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ #ifndef GNUC_or_lint #ifdef lint #define GNUC_or_lint -#endif /* defined lint */ -#ifndef lint +#else /* !defined lint */ #ifdef __GNUC__ #define GNUC_or_lint #endif /* defined __GNUC__ */ @@ -83,8 +109,7 @@ static char elsieid[] = "@(#)zdump.c 7.31"; #ifndef INITIALIZE #ifdef GNUC_or_lint #define INITIALIZE(x) ((x) = 0) -#endif /* defined GNUC_or_lint */ -#ifndef GNUC_or_lint +#else /* !defined GNUC_or_lint */ #define INITIALIZE(x) #endif /* !defined GNUC_or_lint */ #endif /* !defined INITIALIZE */ @@ -96,39 +121,125 @@ static char elsieid[] = "@(#)zdump.c 7.31"; */ #ifndef _ -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #define _(msgid) gettext(msgid) -#else /* !(HAVE_GETTEXT - 0) */ +#else /* !HAVE_GETTEXT */ #define _(msgid) msgid -#endif /* !(HAVE_GETTEXT - 0) */ +#endif /* !HAVE_GETTEXT */ #endif /* !defined _ */ #ifndef TZ_DOMAIN #define TZ_DOMAIN "tz" #endif /* !defined TZ_DOMAIN */ -#ifndef P -#ifdef __STDC__ -#define P(x) x -#endif /* defined __STDC__ */ -#ifndef __STDC__ -#define P(x) () -#endif /* !defined __STDC__ */ -#endif /* !defined P */ - extern char ** environ; -extern int getopt P((int argc, char * const argv[], - const char * options)); +extern int getopt(int argc, char * const argv[], + const char * options); extern char * optarg; extern int optind; extern char * tzname[2]; -static char * abbr P((struct tm * tmp)); -static long delta P((struct tm * newp, struct tm * oldp)); -static time_t hunt P((char * name, time_t lot, time_t hit)); +static time_t absolute_min_time; +static time_t absolute_max_time; static size_t longest; static char * progname; -static void show P((char * zone, time_t t, int v)); +static int warned; + +static char * abbr(struct tm * tmp); +static void abbrok(const char * abbrp, const char * zone); +static long delta(struct tm * newp, struct tm * oldp); +static void dumptime(const struct tm * tmp); +static time_t hunt(char * name, time_t lot, time_t hit); +static void setabsolutes(void); +static void show(char * zone, time_t t, int v); +static const char * tformat(void); +static time_t yeartot(long y); + +#ifndef TYPECHECK +#define my_localtime localtime +#else /* !defined TYPECHECK */ +static struct tm * +my_localtime(tp) +time_t * tp; +{ + register struct tm * tmp; + + tmp = localtime(tp); + if (tp != NULL && tmp != NULL) { + struct tm tm; + register time_t t; + + tm = *tmp; + t = mktime(&tm); + if (t - *tp >= 1 || *tp - t >= 1) { + (void) fflush(stdout); + (void) fprintf(stderr, "\n%s: ", progname); + (void) fprintf(stderr, tformat(), *tp); + (void) fprintf(stderr, " ->"); + (void) fprintf(stderr, " year=%d", tmp->tm_year); + (void) fprintf(stderr, " mon=%d", tmp->tm_mon); + (void) fprintf(stderr, " mday=%d", tmp->tm_mday); + (void) fprintf(stderr, " hour=%d", tmp->tm_hour); + (void) fprintf(stderr, " min=%d", tmp->tm_min); + (void) fprintf(stderr, " sec=%d", tmp->tm_sec); + (void) fprintf(stderr, " isdst=%d", tmp->tm_isdst); + (void) fprintf(stderr, " -> "); + (void) fprintf(stderr, tformat(), t); + (void) fprintf(stderr, "\n"); + } + } + return tmp; +} +#endif /* !defined TYPECHECK */ + +static void +abbrok(abbrp, zone) +const char * const abbrp; +const char * const zone; +{ + register const char * cp; + register char * wp; + + if (warned) + return; + cp = abbrp; + wp = NULL; + while (isascii((unsigned char) *cp) && isalpha((unsigned char) *cp)) + ++cp; + if (cp - abbrp == 0) + wp = _("lacks alphabetic at start"); + else if (cp - abbrp < 3) + wp = _("has fewer than 3 alphabetics"); + else if (cp - abbrp > 6) + wp = _("has more than 6 alphabetics"); + if (wp == NULL && (*cp == '+' || *cp == '-')) { + ++cp; + if (isascii((unsigned char) *cp) && + isdigit((unsigned char) *cp)) + if (*cp++ == '1' && *cp >= '0' && *cp <= '4') + ++cp; + if (*cp != '\0') + wp = _("differs from POSIX standard"); + } + if (wp == NULL) + return; + (void) fflush(stdout); + (void) fprintf(stderr, + _("%s: warning: zone \"%s\" abbreviation \"%s\" %s\n"), + progname, zone, abbrp, wp); + warned = TRUE; +} + +static void +usage(const char *progname, FILE *stream, int status) +{ + (void) fprintf(stream, +_("%s: usage is %s [ --version ] [ --help ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n\ +\n\ +Report bugs to tz@elsie.nci.nih.gov.\n"), + progname, progname); + exit(status); +} int main(argc, argv) @@ -138,72 +249,86 @@ char * argv[]; register int i; register int c; register int vflag; - register char * cutoff; - register int cutyear; - register long cuttime; - char ** fakeenv; + register char * cutarg; + register long cutloyear = ZDUMP_LO_YEAR; + register long cuthiyear = ZDUMP_HI_YEAR; + register time_t cutlotime; + register time_t cuthitime; + register char ** fakeenv; time_t now; time_t t; time_t newt; - time_t hibit; struct tm tm; struct tm newtm; + register struct tm * tmp; + register struct tm * newtmp; - INITIALIZE(cuttime); -#if HAVE_GETTEXT - 0 - (void) setlocale(LC_MESSAGES, ""); + INITIALIZE(cutlotime); + INITIALIZE(cuthitime); +#if HAVE_GETTEXT + (void) setlocale(LC_ALL, ""); #ifdef TZ_DOMAINDIR (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); -#endif /* defined(TEXTDOMAINDIR) */ +#endif /* defined TEXTDOMAINDIR */ (void) textdomain(TZ_DOMAIN); -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ progname = argv[0]; for (i = 1; i < argc; ++i) if (strcmp(argv[i], "--version") == 0) { (void) printf("%s\n", elsieid); - (void) exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); + } else if (strcmp(argv[i], "--help") == 0) { + usage(progname, stdout, EXIT_SUCCESS); } vflag = 0; - cutoff = NULL; + cutarg = NULL; while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v') if (c == 'v') vflag = 1; - else cutoff = optarg; + else cutarg = optarg; if ((c != EOF && c != -1) || (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) { - (void) fprintf(stderr, -_("%s: usage is %s [ --version ] [ -v ] [ -c cutoff ] zonename ...\n"), - argv[0], argv[0]); - (void) exit(EXIT_FAILURE); + usage(progname, stderr, EXIT_FAILURE); } - if (cutoff != NULL) { - int y; + if (vflag) { + if (cutarg != NULL) { + long lo; + long hi; + char dummy; - cutyear = atoi(cutoff); - cuttime = 0; - for (y = EPOCH_YEAR; y < cutyear; ++y) - cuttime += DAYSPERNYEAR + isleap(y); - cuttime *= SECSPERHOUR * HOURSPERDAY; + if (sscanf(cutarg, "%ld%c", &hi, &dummy) == 1) { + cuthiyear = hi; + } else if (sscanf(cutarg, "%ld,%ld%c", + &lo, &hi, &dummy) == 2) { + cutloyear = lo; + cuthiyear = hi; + } else { +(void) fprintf(stderr, _("%s: wild -c argument %s\n"), + progname, cutarg); + exit(EXIT_FAILURE); + } + } + setabsolutes(); + cutlotime = yeartot(cutloyear); + cuthitime = yeartot(cuthiyear); } (void) time(&now); longest = 0; for (i = optind; i < argc; ++i) if (strlen(argv[i]) > longest) longest = strlen(argv[i]); - for (hibit = 1; (hibit << 1) != 0; hibit <<= 1) - continue; { register int from; register int to; - for (i = 0; environ[i] != NULL; ++i) + for (i = 0; environ[i] != NULL; ++i) continue; fakeenv = (char **) malloc((size_t) ((i + 2) * sizeof *fakeenv)); if (fakeenv == NULL || (fakeenv[0] = (char *) malloc(longest + 4)) == NULL) { (void) perror(progname); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } to = 0; (void) strcpy(fakeenv[to++], "TZ="); @@ -221,85 +346,171 @@ _("%s: usage is %s [ --version ] [ -v ] [ -c cutoff ] zonename ...\n"), show(argv[i], now, FALSE); continue; } - /* - ** Get lowest value of t. - */ - t = hibit; - if (t > 0) /* time_t is unsigned */ - t = 0; + warned = FALSE; + t = absolute_min_time; show(argv[i], t, TRUE); t += SECSPERHOUR * HOURSPERDAY; show(argv[i], t, TRUE); - tm = *localtime(&t); - (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1); + if (t < cutlotime) + t = cutlotime; + tmp = my_localtime(&t); + if (tmp != NULL) { + tm = *tmp; + (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1); + } for ( ; ; ) { - if (cutoff != NULL && t >= cuttime) + if (t >= cuthitime || t >= cuthitime - SECSPERHOUR * 12) break; newt = t + SECSPERHOUR * 12; - if (cutoff != NULL && newt >= cuttime) - break; - if (newt <= t) - break; - newtm = *localtime(&newt); - if (delta(&newtm, &tm) != (newt - t) || + newtmp = localtime(&newt); + if (newtmp != NULL) + newtm = *newtmp; + if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) : + (delta(&newtm, &tm) != (newt - t) || newtm.tm_isdst != tm.tm_isdst || - strcmp(abbr(&newtm), buf) != 0) { + strcmp(abbr(&newtm), buf) != 0)) { newt = hunt(argv[i], t, newt); - newtm = *localtime(&newt); - (void) strncpy(buf, abbr(&newtm), - (sizeof buf) - 1); + newtmp = localtime(&newt); + if (newtmp != NULL) { + newtm = *newtmp; + (void) strncpy(buf, + abbr(&newtm), + (sizeof buf) - 1); + } } t = newt; tm = newtm; + tmp = newtmp; } - /* - ** Get highest value of t. - */ - t = ~((time_t) 0); - if (t < 0) /* time_t is signed */ - t &= ~hibit; + t = absolute_max_time; t -= SECSPERHOUR * HOURSPERDAY; show(argv[i], t, TRUE); t += SECSPERHOUR * HOURSPERDAY; show(argv[i], t, TRUE); } if (fflush(stdout) || ferror(stdout)) { - (void) fprintf(stderr, "%s: ", argv[0]); - (void) perror(_("Error writing standard output")); - (void) exit(EXIT_FAILURE); + (void) fprintf(stderr, "%s: ", progname); + (void) perror(_("Error writing to standard output")); + exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); + /* If exit fails to exit... */ + return EXIT_FAILURE; +} - /* gcc -Wall pacifier */ - for ( ; ; ) - continue; +static void +setabsolutes(void) +{ + if (0.5 == (time_t) 0.5) { + /* + ** time_t is floating. + */ + if (sizeof (time_t) == sizeof (float)) { + absolute_min_time = (time_t) -FLT_MAX; + absolute_max_time = (time_t) FLT_MAX; + } else if (sizeof (time_t) == sizeof (double)) { + absolute_min_time = (time_t) -DBL_MAX; + absolute_max_time = (time_t) DBL_MAX; + } else { + (void) fprintf(stderr, +_("%s: use of -v on system with floating time_t other than float or double\n"), + progname); + exit(EXIT_FAILURE); + } + } else if (0 > (time_t) -1) { + /* + ** time_t is signed. Assume overflow wraps around. + */ + time_t t = 0; + time_t t1 = 1; + + while (t < t1) { + t = t1; + t1 = 2 * t1 + 1; + } + + absolute_max_time = t; + t = -t; + absolute_min_time = t - 1; + if (t < absolute_min_time) + absolute_min_time = t; + } else { + /* + ** time_t is unsigned. + */ + absolute_min_time = 0; + absolute_max_time = absolute_min_time - 1; + } } static time_t -hunt(name, lot, hit) -char * name; -time_t lot; -time_t hit; +yeartot(y) +const long y; { - time_t t; - struct tm lotm; - struct tm tm; - static char loab[MAX_STRING_LENGTH]; + register long myy; + register long seconds; + register time_t t; - lotm = *localtime(&lot); - (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1); - while ((hit - lot) >= 2) { - t = lot / 2 + hit / 2; + myy = EPOCH_YEAR; + t = 0; + while (myy != y) { + if (myy < y) { + seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR; + ++myy; + if (t > absolute_max_time - seconds) { + t = absolute_max_time; + break; + } + t += seconds; + } else { + --myy; + seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR; + if (t < absolute_min_time + seconds) { + t = absolute_min_time; + break; + } + t -= seconds; + } + } + return t; +} + +static time_t +hunt(char *name, time_t lot, time_t hit) +{ + time_t t; + long diff; + struct tm lotm; + register struct tm * lotmp; + struct tm tm; + register struct tm * tmp; + char loab[MAX_STRING_LENGTH]; + + lotmp = my_localtime(&lot); + if (lotmp != NULL) { + lotm = *lotmp; + (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1); + } + for ( ; ; ) { + diff = (long) (hit - lot); + if (diff < 2) + break; + t = lot; + t += diff / 2; if (t <= lot) ++t; else if (t >= hit) --t; - tm = *localtime(&t); - if (delta(&tm, &lotm) == (t - lot) && + tmp = my_localtime(&t); + if (tmp != NULL) + tm = *tmp; + if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) : + (delta(&tm, &lotm) == (t - lot) && tm.tm_isdst == lotm.tm_isdst && - strcmp(abbr(&tm), loab) == 0) { + strcmp(abbr(&tm), loab) == 0)) { lot = t; lotm = tm; + lotmp = tmp; } else hit = t; } show(name, lot, TRUE); @@ -308,7 +519,7 @@ time_t hit; } /* -** Thanks to Paul Eggert (eggert@twinsun.com) for logic used in delta. +** Thanks to Paul Eggert for logic used in delta. */ static long @@ -316,14 +527,14 @@ delta(newp, oldp) struct tm * newp; struct tm * oldp; { - long result; - int tmy; + register long result; + register int tmy; if (newp->tm_year < oldp->tm_year) return -delta(oldp, newp); result = 0; for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy) - result += DAYSPERNYEAR + isleap(tmy + TM_YEAR_BASE); + result += DAYSPERNYEAR + isleap_sum(tmy, TM_YEAR_BASE); result += newp->tm_yday - oldp->tm_yday; result *= HOURSPERDAY; result += newp->tm_hour - oldp->tm_hour; @@ -335,27 +546,36 @@ struct tm * oldp; } static void -show(zone, t, v) -char * zone; -time_t t; -int v; +show(char *zone, time_t t, int v) { - struct tm * tmp; + register struct tm * tmp; (void) printf("%-*s ", (int) longest, zone); - if (v) - (void) printf("%.24s UTC = ", asctime(gmtime(&t))); - tmp = localtime(&t); - (void) printf("%.24s", asctime(tmp)); - if (*abbr(tmp) != '\0') - (void) printf(" %s", abbr(tmp)); if (v) { - (void) printf(" isdst=%d", tmp->tm_isdst); + tmp = gmtime(&t); + if (tmp == NULL) { + (void) printf(tformat(), t); + } else { + dumptime(tmp); + (void) printf(" UTC"); + } + (void) printf(" = "); + } + tmp = my_localtime(&t); + dumptime(tmp); + if (tmp != NULL) { + if (*abbr(tmp) != '\0') + (void) printf(" %s", abbr(tmp)); + if (v) { + (void) printf(" isdst=%d", tmp->tm_isdst); #ifdef TM_GMTOFF - (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF); + (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF); #endif /* defined TM_GMTOFF */ + } } (void) printf("\n"); + if (tmp != NULL && *abbr(tmp) != '\0') + abbrok(abbr(tmp), zone); } static char * @@ -370,3 +590,84 @@ struct tm * tmp; result = tzname[tmp->tm_isdst]; return (result == NULL) ? &nada : result; } + +/* +** The code below can fail on certain theoretical systems; +** it works on all known real-world systems as of 2004-12-30. +*/ + +static const char * +tformat(void) +{ + if (0.5 == (time_t) 0.5) { /* floating */ + if (sizeof (time_t) > sizeof (double)) + return "%Lg"; + return "%g"; + } + if (0 > (time_t) -1) { /* signed */ + if (sizeof (time_t) > sizeof (long)) + return "%lld"; + if (sizeof (time_t) > sizeof (int)) + return "%ld"; + return "%d"; + } + if (sizeof (time_t) > sizeof (unsigned long)) + return "%llu"; + if (sizeof (time_t) > sizeof (unsigned int)) + return "%lu"; + return "%u"; +} + +static void +dumptime(timeptr) +register const struct tm * timeptr; +{ + static const char wday_name[][3] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + static const char mon_name[][3] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + register const char * wn; + register const char * mn; + register int lead; + register int trail; + + if (timeptr == NULL) { + (void) printf("NULL"); + return; + } + /* + ** The packaged versions of localtime and gmtime never put out-of-range + ** values in tm_wday or tm_mon, but since this code might be compiled + ** with other (perhaps experimental) versions, paranoia is in order. + */ + if (timeptr->tm_wday < 0 || timeptr->tm_wday >= + (int) (sizeof wday_name / sizeof wday_name[0])) + wn = "???"; + else wn = wday_name[timeptr->tm_wday]; + if (timeptr->tm_mon < 0 || timeptr->tm_mon >= + (int) (sizeof mon_name / sizeof mon_name[0])) + mn = "???"; + else mn = mon_name[timeptr->tm_mon]; + (void) printf("%.3s %.3s%3d %.2d:%.2d:%.2d ", + wn, mn, + timeptr->tm_mday, timeptr->tm_hour, + timeptr->tm_min, timeptr->tm_sec); +#define DIVISOR 10 + trail = timeptr->tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR; + lead = timeptr->tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR + + trail / DIVISOR; + trail %= DIVISOR; + if (trail < 0 && lead > 0) { + trail += DIVISOR; + --lead; + } else if (lead < 0 && trail > 0) { + trail -= DIVISOR; + ++lead; + } + if (lead == 0) + (void) printf("%d", trail); + else (void) printf("%d%d", lead, ((trail < 0) ? -trail : trail)); +} diff --git a/zic/zic.8 b/zic/zic.8 index 86b13544f971..f842927a7b7e 100644 --- a/zic/zic.8 +++ b/zic/zic.8 @@ -269,7 +269,7 @@ A zone line has the form .nf .ti +.5i .ta \w'Zone\0\0'u +\w'Australia/Adelaide\0\0'u +\w'GMTOFF\0\0'u +\w'RULES/SAVE\0\0'u +\w'FORMAT\0\0'u -Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL] +Zone NAME GMTOFF RULES/SAVE FORMAT [UNTILYEAR [MONTH [DAY [TIME]]]] .sp For example: .sp @@ -311,15 +311,15 @@ Alternately, a slash (/) separates standard and daylight abbreviations. .TP -.B UNTIL +.B UNTILYEAR [MONTH [DAY [TIME]]] The time at which the UTC offset or the rule(s) change for a location. It is specified as a year, a month, a day, and a time of day. If this is specified, the time zone information is generated from the given UTC offset and rule change until the time specified. The month, day, and time of day have the same format as the IN, ON, and AT -columns of a rule; trailing columns can be omitted, and default to the -earliest possible value for the missing columns. +fields of a rule; trailing fields can be omitted, and default to the +earliest possible value for the missing fields. .IP The next line must be a .q continuation @@ -328,11 +328,11 @@ string .q Zone and the name are omitted, as the continuation line will place information starting at the time specified as the -.B UNTIL -field in the previous line in the file used by the previous line. -Continuation lines may contain an -.B UNTIL -field, just as zone lines do, indicating that the next line is a further +.q until +information in the previous line in the file used by the previous line. +Continuation lines may contain +.q until +information, just as zone lines do, indicating that the next line is a further continuation. .PP A link line has the form @@ -411,14 +411,83 @@ or .q Rolling if the leap second time given by the other fields should be interpreted as local wall clock time. -.SH NOTE +.SH "EXTENDED EXAMPLE" +Here is an extended example of +.I zic +input, intended to illustrate many of its features. +.br +.ne 22 +.nf +.in +2m +.ta \w'# Rule\0\0'u +\w'NAME\0\0'u +\w'FROM\0\0'u +\w'1973\0\0'u +\w'TYPE\0\0'u +\w'Apr\0\0'u +\w'lastSun\0\0'u +\w'2:00\0\0'u +\w'SAVE\0\0'u +.sp +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Swiss 1940 only - Nov 2 0:00 1:00 S +Rule Swiss 1940 only - Dec 31 0:00 0 - +Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 S +Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0 +.sp .5 +Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S +Rule EU 1977 only - Sep lastSun 1:00u 0 - +Rule EU 1978 only - Oct 1 1:00u 0 - +Rule EU 1979 1995 - Sep lastSun 1:00u 0 - +Rule EU 1981 max - Mar lastSun 1:00u 1:00 S +Rule EU 1996 max - Oct lastSun 1:00u 0 - +.sp +.ta \w'# Zone\0\0'u +\w'Europe/Zurich\0\0'u +\w'0:34:08\0\0'u +\w'RULES/SAVE\0\0'u +\w'FORMAT\0\0'u +# Zone NAME GMTOFF RULES FORMAT UNTIL +Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12 + 0:29:44 - BMT 1894 Jun + 1:00 Swiss CE%sT 1981 + 1:00 EU CE%sT +.sp +Link Europe/Zurich Switzerland +.sp +.in +.fi +In this example, the zone is named Europe/Zurich but it has an alias +as Switzerland. Zurich was 34 minutes and 8 seconds west of GMT until +1848-09-12 at 00:00, when the offset changed to 29 minutes and 44 +seconds. After 1894-06-01 at 00:00 Swiss daylight saving rules (defined +with lines beginning with "Rule Swiss") apply, and the GMT offset +became one hour. From 1981 to the present, EU daylight saving rules have +applied, and the UTC offset has remained at one hour. +.PP +In 1940, daylight saving time applied from November 2 at 00:00 to +December 31 at 00:00. In 1941 and 1942, daylight saving time applied +from the first Sunday in May at 02:00 to the first Sunday in October +at 00:00. +The pre-1981 EU daylight-saving rules have no effect +here, but are included for completeness. Since 1981, daylight +saving has begun on the last Sunday in March at 01:00 UTC. +Until 1995 it ended the last Sunday in September at 01:00 UTC, +but this changed to the last Sunday in October starting in 1996. +.PP +For purposes of +display, "LMT" and "BMT" were initially used, respectively. Since +Swiss rules and later EU rules were applied, the display name for the +timezone has been CET for standard time and CEST for daylight saving +time. +.SH NOTES For areas with more than two types of local time, you may need to use local standard time in the .B AT field of the earliest transition time's rule to ensure that the earliest transition time recorded in the compiled file is correct. +.PP +If, +for a particular zone, +a clock advance caused by the start of daylight saving +coincides with and is equal to +a clock retreat caused by a change in UTC offset, +.IR zic +produces a single transition to daylight saving at the new UTC offset +(without any change in wall clock time). +To get separate transitions +use multiple zone continuation lines +specifying transition instants using universal time. .SH FILE /usr/local/etc/zoneinfo standard directory used for created files .SH "SEE ALSO" newctime(3), tzfile(5), zdump(8) -.\" @(#)zic.8 7.22 +.\" @(#)zic.8 8.4 diff --git a/zic/zic.c b/zic/zic.c index 1a046ff3ed92..01d9f135bd7a 100644 --- a/zic/zic.c +++ b/zic/zic.c @@ -1,9 +1,22 @@ -static char elsieid[] = "@(#)zic.c 7.116"; +/* +** This file is in the public domain, so clarified as of +** 2006-07-17 by Arthur David Olson. +*/ + +static char elsieid[] = "@(#)zic.c 8.19"; #include "private.h" #include "locale.h" #include "tzfile.h" +#define ZIC_VERSION '2' + +typedef int_fast64_t zic_t; + +#ifndef ZIC_MAX_ABBR_LEN_WO_WARN +#define ZIC_MAX_ABBR_LEN_WO_WARN 6 +#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */ + #if HAVE_SYS_STAT_H #include "sys/stat.h" #endif @@ -15,7 +28,7 @@ static char elsieid[] = "@(#)zic.c 7.116"; /* ** On some ancient hosts, predicates like `isspace(C)' are defined -** only if isascii(C) || C == EOF. Modern hosts obey the C Standard, +** only if isascii(C) || C == EOF. Modern hosts obey the C Standard, ** which says they are defined only if C == ((unsigned char) C) || C == EOF. ** Neither the C Standard nor Posix require that `isascii' exist. ** For portability, we check both ancient and modern requirements. @@ -26,6 +39,11 @@ static char elsieid[] = "@(#)zic.c 7.116"; #define isascii(x) 1 #endif +#define OFFSET_STRLEN_MAXIMUM (7 + INT_STRLEN_MAXIMUM(long)) +#define RULE_STRLEN_MAXIMUM 8 /* "Mdd.dd.d" */ + +#define end(cp) (strchr((cp), '\0')) + struct rule { const char * r_filename; int r_linenum; @@ -34,6 +52,8 @@ struct rule { int r_loyear; /* for example, 1986 */ int r_hiyear; /* for example, 1986 */ const char * r_yrtype; + int r_lowasnum; + int r_hiwasnum; int r_month; /* 0..11 */ @@ -50,7 +70,7 @@ struct rule { const char * r_abbrvar; /* variable part of abbreviation */ int r_todo; /* a rule to do (used in outzone) */ - time_t r_temp; /* used in outzone */ + zic_t r_temp; /* used in outzone */ }; /* @@ -76,77 +96,84 @@ struct zone { int z_nrules; struct rule z_untilrule; - time_t z_untiltime; + zic_t z_untiltime; }; -extern int getopt P((int argc, char * const argv[], - const char * options)); -extern int link P((const char * fromname, const char * toname)); +extern int getopt(int argc, char * const argv[], + const char * options); +extern int link(const char * fromname, const char * toname); extern char * optarg; extern int optind; -static void addtt P((time_t starttime, int type)); -static int addtype P((long gmtoff, const char * abbr, int isdst, - int ttisstd, int ttisgmt)); -static void leapadd P((time_t t, int positive, int rolling, int count)); -static void adjleap P((void)); -static void associate P((void)); -static int ciequal P((const char * ap, const char * bp)); -static void convert P((long val, char * buf)); -static void dolink P((const char * fromfile, const char * tofile)); -static void doabbr P((char * abbr, const char * format, - const char * letters, int isdst)); -static void eat P((const char * name, int num)); -static void eats P((const char * name, int num, - const char * rname, int rnum)); -static long eitol P((int i)); -static void error P((const char * message)); -static char ** getfields P((char * buf)); -static long gethms P((const char * string, const char * errstrng, - int signable)); -static void infile P((const char * filename)); -static void inleap P((char ** fields, int nfields)); -static void inlink P((char ** fields, int nfields)); -static void inrule P((char ** fields, int nfields)); -static int inzcont P((char ** fields, int nfields)); -static int inzone P((char ** fields, int nfields)); -static int inzsub P((char ** fields, int nfields, int iscont)); -static int itsabbr P((const char * abbr, const char * word)); -static int itsdir P((const char * name)); -static int lowerit P((int c)); -static char * memcheck P((char * tocheck)); -static int mkdirs P((char * filename)); -static void newabbr P((const char * abbr)); -static long oadd P((long t1, long t2)); -static void outzone P((const struct zone * zp, int ntzones)); -static void puttzcode P((long code, FILE * fp)); -static int rcomp P((const void * leftp, const void * rightp)); -static time_t rpytime P((const struct rule * rp, int wantedy)); -static void rulesub P((struct rule * rp, +static void addtt(zic_t starttime, int type); +static int addtype(long gmtoff, const char * abbr, int isdst, + int ttisstd, int ttisgmt); +static void leapadd(zic_t t, int positive, int rolling, int count); +static void adjleap(void); +static void associate(void); +static int ciequal(const char * ap, const char * bp); +static void convert(long val, char * buf); +static void convert64(zic_t val, char * buf); +static void dolink(const char * fromfield, const char * tofield); +static void doabbr(char * abbr, const char * format, + const char * letters, int isdst, int doquotes); +static void eat(const char * name, int num); +static void eats(const char * name, int num, + const char * rname, int rnum); +static long eitol(int i); +static void error(const char * message); +static char ** getfields(char * buf); +static long gethms(const char * string, const char * errstrng, + int signable); +static void infile(const char * filename); +static void inleap(char ** fields, int nfields); +static void inlink(char ** fields, int nfields); +static void inrule(char ** fields, int nfields); +static int inzcont(char ** fields, int nfields); +static int inzone(char ** fields, int nfields); +static int inzsub(char ** fields, int nfields, int iscont); +static int is32(zic_t x); +static int itsabbr(const char * abbr, const char * word); +static int itsdir(const char * name); +static int lowerit(int c); +static char * memcheck(char * tocheck); +static int mkdirs(char * filename); +static void newabbr(const char * abbr); +static long oadd(long t1, long t2); +static void outzone(const struct zone * zp, int ntzones); +static void puttzcode(long code, FILE * fp); +static void puttzcode64(zic_t code, FILE * fp); +static int rcomp(const void * leftp, const void * rightp); +static zic_t rpytime(const struct rule * rp, int wantedy); +static void rulesub(struct rule * rp, const char * loyearp, const char * hiyearp, const char * typep, const char * monthp, - const char * dayp, const char * timep)); -static void setboundaries P((void)); -static time_t tadd P((time_t t1, long t2)); -static void usage P((void)); -static void writezone P((const char * name)); -static int yearistype P((int year, const char * type)); - -#if !(HAVE_STRERROR - 0) -static char * strerror P((int)); -#endif /* !(HAVE_STRERROR - 0) */ + const char * dayp, const char * timep); +static int stringoffset(char * result, long offset); +static int stringrule(char * result, const struct rule * rp, + long dstoff, long gmtoff); +static void stringzone(char * result, + const struct zone * zp, int ntzones); +static void setboundaries(void); +static zic_t tadd(zic_t t1, long t2); +static void usage(FILE *stream, int status); +static void writezone(const char * name, const char * string); +static int yearistype(int year, const char * type); static int charcnt; static int errors; static const char * filename; static int leapcnt; +static int leapseen; +static int leapminyear; +static int leapmaxyear; static int linenum; -static time_t max_time; +static int max_abbrvar_len; +static int max_format_len; +static zic_t max_time; static int max_year; -static int max_year_representable; -static time_t min_time; +static zic_t min_time; static int min_year; -static int min_year_representable; static int noise; static const char * rfilename; static int rlinenum; @@ -256,8 +283,8 @@ struct lookup { const int l_value; }; -static struct lookup const * byword P((const char * string, - const struct lookup * lp)); +static struct lookup const * byword(const char * string, + const struct lookup * lp); static struct lookup const line_codes[] = { { "Rule", LC_RULE }, @@ -334,7 +361,7 @@ static const int len_years[2] = { }; static struct attype { - time_t at; + zic_t at; unsigned char type; } attypes[TZ_MAX_TIMES]; static long gmtoffs[TZ_MAX_TYPES]; @@ -343,7 +370,7 @@ static unsigned char abbrinds[TZ_MAX_TYPES]; static char ttisstds[TZ_MAX_TYPES]; static char ttisgmts[TZ_MAX_TYPES]; static char chars[TZ_MAX_CHARS]; -static time_t trans[TZ_MAX_LEAPS]; +static zic_t trans[TZ_MAX_LEAPS]; static long corr[TZ_MAX_LEAPS]; static char roll[TZ_MAX_LEAPS]; @@ -360,7 +387,7 @@ char * const ptr; (void) fprintf(stderr, _("%s: Memory exhausted: %s\n"), progname, e); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } return ptr; } @@ -374,19 +401,6 @@ char * const ptr; ** Error handling. */ -#if !(HAVE_STRERROR - 0) -static char * -strerror(errnum) -int errnum; -{ - extern char * sys_errlist[]; - extern int sys_nerr; - - return (errnum > 0 && errnum <= sys_nerr) ? - sys_errlist[errnum] : _("Unknown system error"); -} -#endif /* !(HAVE_STRERROR - 0) */ - static void eats(name, num, rname, rnum) const char * const name; @@ -440,11 +454,15 @@ const char * const string; } static void -usage P((void)) +usage(FILE *stream, int status) { - (void) fprintf(stderr, _("%s: usage is %s [ --version ] [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"), - progname, progname); - (void) exit(EXIT_FAILURE); + (void) fprintf(stream, _("%s: usage is %s \ +[ --version ] [ --help ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\ +\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n\ +\n\ +Report bugs to tz@elsie.nci.nih.gov.\n"), + progname, progname); + exit(status); } static const char * psxrules; @@ -452,7 +470,6 @@ static const char * lcltime; static const char * directory; static const char * leapsec; static const char * yitcommand; -static int sflag = FALSE; int main(argc, argv) @@ -466,23 +483,30 @@ char * argv[]; #ifdef unix (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); #endif /* defined unix */ -#if HAVE_GETTEXT - 0 - (void) setlocale(LC_MESSAGES, ""); +#if HAVE_GETTEXT + (void) setlocale(LC_ALL, ""); #ifdef TZ_DOMAINDIR (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); #endif /* defined TEXTDOMAINDIR */ (void) textdomain(TZ_DOMAIN); -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ progname = argv[0]; + if (TYPE_BIT(zic_t) < 64) { + (void) fprintf(stderr, "%s: %s\n", progname, + _("wild compilation-time specification of zic_t")); + exit(EXIT_FAILURE); + } for (i = 1; i < argc; ++i) if (strcmp(argv[i], "--version") == 0) { (void) printf("%s\n", elsieid); - (void) exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); + } else if (strcmp(argv[i], "--help") == 0) { + usage(stdout, EXIT_SUCCESS); } while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF && c != -1) switch (c) { default: - usage(); + usage(stderr, EXIT_FAILURE); case 'd': if (directory == NULL) directory = optarg; @@ -490,7 +514,7 @@ char * argv[]; (void) fprintf(stderr, _("%s: More than one -d option specified\n"), progname); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } break; case 'l': @@ -500,7 +524,7 @@ _("%s: More than one -d option specified\n"), (void) fprintf(stderr, _("%s: More than one -l option specified\n"), progname); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } break; case 'p': @@ -510,7 +534,7 @@ _("%s: More than one -l option specified\n"), (void) fprintf(stderr, _("%s: More than one -p option specified\n"), progname); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } break; case 'y': @@ -520,7 +544,7 @@ _("%s: More than one -p option specified\n"), (void) fprintf(stderr, _("%s: More than one -y option specified\n"), progname); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } break; case 'L': @@ -530,18 +554,18 @@ _("%s: More than one -y option specified\n"), (void) fprintf(stderr, _("%s: More than one -L option specified\n"), progname); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } break; case 'v': noise = TRUE; break; case 's': - sflag = TRUE; + (void) printf("%s: -s ignored\n", progname); break; } if (optind == argc - 1 && strcmp(argv[optind], "=") == 0) - usage(); /* usage message by request */ + usage(stderr, EXIT_FAILURE); /* usage message by request */ if (directory == NULL) directory = TZDIR; if (yitcommand == NULL) @@ -557,7 +581,7 @@ _("%s: More than one -L option specified\n"), for (i = optind; i < argc; ++i) infile(argv[i]); if (errors) - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); associate(); for (i = 0; i < nzones; i = j) { /* @@ -573,6 +597,11 @@ _("%s: More than one -L option specified\n"), for (i = 0; i < nlinks; ++i) { eat(links[i].l_filename, links[i].l_linenum); dolink(links[i].l_from, links[i].l_to); + if (noise) + for (j = 0; j < nlinks; ++j) + if (strcmp(links[i].l_to, + links[j].l_from) == 0) + warning(_("link to link")); } if (lcltime != NULL) { eat("command line", 1); @@ -586,26 +615,26 @@ _("%s: More than one -L option specified\n"), } static void -dolink(fromfile, tofile) -const char * const fromfile; -const char * const tofile; +dolink(fromfield, tofield) +const char * const fromfield; +const char * const tofield; { register char * fromname; register char * toname; - if (fromfile[0] == '/') - fromname = ecpyalloc(fromfile); + if (fromfield[0] == '/') + fromname = ecpyalloc(fromfield); else { fromname = ecpyalloc(directory); fromname = ecatalloc(fromname, "/"); - fromname = ecatalloc(fromname, fromfile); + fromname = ecatalloc(fromname, fromfield); } - if (tofile[0] == '/') - toname = ecpyalloc(tofile); + if (tofield[0] == '/') + toname = ecpyalloc(tofield); else { toname = ecpyalloc(directory); toname = ecatalloc(toname, "/"); - toname = ecatalloc(toname, tofile); + toname = ecatalloc(toname, tofield); } /* ** We get to be careful here since @@ -617,75 +646,54 @@ const char * const tofile; int result; if (mkdirs(toname) != 0) - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); result = link(fromname, toname); -#if (HAVE_SYMLINK - 0) +#if HAVE_SYMLINK if (result != 0 && - access(fromname, F_OK) == 0 && - !itsdir(fromname)) { - const char *s = tofile; - register char * symlinkcontents = NULL; - while ((s = strchr(s+1, '/')) != NULL) - symlinkcontents = ecatalloc(symlinkcontents, "../"); - symlinkcontents = ecatalloc(symlinkcontents, fromfile); + access(fromname, F_OK) == 0 && + !itsdir(fromname)) { + const char *s = tofield; + register char * symlinkcontents = NULL; - result = symlink(symlinkcontents, toname); - if (result == 0) + while ((s = strchr(s+1, '/')) != NULL) + symlinkcontents = + ecatalloc(symlinkcontents, + "../"); + symlinkcontents = + ecatalloc(symlinkcontents, + fromname); + result = symlink(symlinkcontents, + toname); + if (result == 0) warning(_("hard link failed, symbolic link used")); - ifree(symlinkcontents); + ifree(symlinkcontents); } -#endif +#endif /* HAVE_SYMLINK */ if (result != 0) { const char *e = strerror(errno); (void) fprintf(stderr, _("%s: Can't link from %s to %s: %s\n"), progname, fromname, toname, e); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } } ifree(fromname); ifree(toname); } -#ifndef INT_MAX -#define INT_MAX ((int) (((unsigned)~0)>>1)) -#endif /* !defined INT_MAX */ - -#ifndef INT_MIN -#define INT_MIN ((int) ~(((unsigned)~0)>>1)) -#endif /* !defined INT_MIN */ - -/* -** The tz file format currently allows at most 32-bit quantities. -** This restriction should be removed before signed 32-bit values -** wrap around in 2038, but unfortunately this will require a -** change to the tz file format. -*/ - -#define MAX_BITS_IN_FILE 32 -#define TIME_T_BITS_IN_FILE ((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? TYPE_BIT(time_t) : MAX_BITS_IN_FILE) +#define TIME_T_BITS_IN_FILE 64 static void -setboundaries P((void)) +setboundaries(void) { - if (TYPE_SIGNED(time_t)) { - min_time = ~ (time_t) 0; - min_time <<= TIME_T_BITS_IN_FILE - 1; - max_time = ~ (time_t) 0 - min_time; - if (sflag) - min_time = 0; - } else { - min_time = 0; - max_time = 2 - sflag; - max_time <<= TIME_T_BITS_IN_FILE - 1; - --max_time; - } - min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year; - max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year; - min_year_representable = min_year; - max_year_representable = max_year; + register int i; + + min_time = -1; + for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i) + min_time *= 2; + max_time = -(min_time + 1); } static int @@ -720,7 +728,7 @@ const void * cp2; } static void -associate P((void)) +associate(void) { register struct zone * zp; register struct rule * rp; @@ -782,7 +790,7 @@ associate P((void)) */ eat(zp->z_filename, zp->z_linenum); zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"), - TRUE); + TRUE); /* ** Note, though, that if there's no rule, ** a '%s' in the format is a bad thing. @@ -792,7 +800,7 @@ associate P((void)) } } if (errors) - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } static void @@ -816,7 +824,7 @@ const char * name; (void) fprintf(stderr, _("%s: Can't open %s: %s\n"), progname, name, e); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } wantcont = FALSE; for (num = 1; ; ++num) { @@ -826,7 +834,7 @@ const char * name; cp = strchr(buf, '\n'); if (cp == NULL) { error(_("line too long")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } *cp = '\0'; fields = getfields(buf); @@ -870,7 +878,7 @@ _("%s: Leap line in non leap seconds file %s\n"), (void) fprintf(stderr, _("%s: panic: Invalid l_value %d\n"), progname, lp->l_value); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } } ifree((char *) fields); @@ -878,14 +886,14 @@ _("%s: panic: Invalid l_value %d\n"), if (ferror(fp)) { (void) fprintf(stderr, _("%s: Error reading %s\n"), progname, filename); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } if (fp != stdin && fclose(fp)) { const char *e = strerror(errno); (void) fprintf(stderr, _("%s: Error closing %s: %s\n"), progname, filename, e); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } if (wantcont) error(_("expected continuation line not found")); @@ -905,7 +913,8 @@ const char * string; const char * const errstring; const int signable; { - int hh, mm, ss, sign; + long hh; + int mm, ss, sign; if (string == NULL || *string == '\0') return 0; @@ -915,27 +924,32 @@ const int signable; sign = -1; ++string; } else sign = 1; - if (sscanf(string, scheck(string, "%d"), &hh) == 1) + if (sscanf(string, scheck(string, "%ld"), &hh) == 1) mm = ss = 0; - else if (sscanf(string, scheck(string, "%d:%d"), &hh, &mm) == 2) + else if (sscanf(string, scheck(string, "%ld:%d"), &hh, &mm) == 2) ss = 0; - else if (sscanf(string, scheck(string, "%d:%d:%d"), + else if (sscanf(string, scheck(string, "%ld:%d:%d"), &hh, &mm, &ss) != 3) { error(errstring); return 0; } - if ((hh < 0 || hh >= HOURSPERDAY || + if (hh < 0 || mm < 0 || mm >= MINSPERHOUR || - ss < 0 || ss > SECSPERMIN) && - !(hh == HOURSPERDAY && mm == 0 && ss == 0)) { + ss < 0 || ss > SECSPERMIN) { error(errstring); return 0; } - if (noise && hh == HOURSPERDAY) + if (LONG_MAX / SECSPERHOUR < hh) { + error(_("time overflow")); + return 0; + } + if (noise && hh == HOURSPERDAY && mm == 0 && ss == 0) warning(_("24:00 not handled by pre-1998 versions of zic")); - return eitol(sign) * - (eitol(hh * MINSPERHOUR + mm) * - eitol(SECSPERMIN) + eitol(ss)); + if (noise && (hh > HOURSPERDAY || + (hh == HOURSPERDAY && (mm != 0 || ss != 0)))) +warning(_("values over 24 hours not handled by pre-2007 versions of zic")); + return oadd(eitol(sign) * hh * eitol(SECSPERHOUR), + eitol(sign) * (eitol(mm) * eitol(SECSPERMIN) + eitol(ss))); } static void @@ -960,6 +974,8 @@ const int nfields; fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]); r.r_name = ecpyalloc(fields[RF_NAME]); r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]); + if (max_abbrvar_len < strlen(r.r_abbrvar)) + max_abbrvar_len = strlen(r.r_abbrvar); rules = (struct rule *) (void *) erealloc((char *) rules, (int) ((nrules + 1) * sizeof *rules)); rules[nrules++] = r; @@ -1065,6 +1081,8 @@ const int iscont; } z.z_rule = ecpyalloc(fields[i_rule]); z.z_format = ecpyalloc(fields[i_format]); + if (max_format_len < strlen(z.z_format)) + max_format_len = strlen(z.z_format); hasuntil = nfields > i_untilyear; if (hasuntil) { z.z_untilrule.r_filename = filename; @@ -1085,7 +1103,9 @@ const int iscont; zones[nzones - 1].z_untiltime > min_time && zones[nzones - 1].z_untiltime < max_time && zones[nzones - 1].z_untiltime >= z.z_untiltime) { - error(_("Zone continuation line end time is not after end time of previous line")); + error(_( +"Zone continuation line end time is not after end time of previous line" + )); return FALSE; } } @@ -1109,7 +1129,7 @@ const int nfields; register int i, j; int year, month, day; long dayoff, tod; - time_t t; + zic_t t; if (nfields != LEAP_FIELDS) { error(_("wrong number of fields on Leap line")); @@ -1118,12 +1138,17 @@ const int nfields; dayoff = 0; cp = fields[LP_YEAR]; if (sscanf(cp, scheck(cp, "%d"), &year) != 1) { - /* - * Leapin' Lizards! - */ - error(_("invalid leaping year")); - return; + /* + ** Leapin' Lizards! + */ + error(_("invalid leaping year")); + return; } + if (!leapseen || leapmaxyear < year) + leapmaxyear = year; + if (!leapseen || leapminyear > year) + leapminyear = year; + leapseen = TRUE; j = EPOCH_YEAR; while (j != year) { if (year > j) { @@ -1153,7 +1178,7 @@ const int nfields; return; } dayoff = oadd(dayoff, eitol(day - 1)); - if (dayoff < 0 && !TYPE_SIGNED(time_t)) { + if (dayoff < 0 && !TYPE_SIGNED(zic_t)) { error(_("time before zero")); return; } @@ -1165,7 +1190,7 @@ const int nfields; error(_("time too large")); return; } - t = (time_t) dayoff * SECSPERDAY; + t = (zic_t) dayoff * SECSPERDAY; tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE); cp = fields[LP_CORR]; { @@ -1189,7 +1214,9 @@ const int nfields; return; } if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) { - error(_("illegal Rolling/Stationary field on Leap line")); + error(_( + "illegal Rolling/Stationary field on Leap line" + )); return; } leapadd(tadd(t, tod), positive, lp->l_value, count); @@ -1276,7 +1303,8 @@ const char * const timep; */ cp = loyearp; lp = byword(cp, begin_years); - if (lp != NULL) switch ((int) lp->l_value) { + rp->r_lowasnum = lp == NULL; + if (!rp->r_lowasnum) switch ((int) lp->l_value) { case YR_MINIMUM: rp->r_loyear = INT_MIN; break; @@ -1287,18 +1315,15 @@ const char * const timep; (void) fprintf(stderr, _("%s: panic: Invalid l_value %d\n"), progname, lp->l_value); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) { error(_("invalid starting year")); return; - } else if (noise) { - if (rp->r_loyear < min_year_representable) - warning(_("starting year too low to be represented")); - else if (rp->r_loyear > max_year_representable) - warning(_("starting year too high to be represented")); } cp = hiyearp; - if ((lp = byword(cp, end_years)) != NULL) switch ((int) lp->l_value) { + lp = byword(cp, end_years); + rp->r_hiwasnum = lp == NULL; + if (!rp->r_hiwasnum) switch ((int) lp->l_value) { case YR_MINIMUM: rp->r_hiyear = INT_MIN; break; @@ -1312,15 +1337,10 @@ const char * const timep; (void) fprintf(stderr, _("%s: panic: Invalid l_value %d\n"), progname, lp->l_value); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) { error(_("invalid ending year")); return; - } else if (noise) { - if (rp->r_loyear < min_year_representable) - warning(_("ending year too low to be represented")); - else if (rp->r_loyear > max_year_representable) - warning(_("ending year too high to be represented")); } if (rp->r_loyear > rp->r_hiyear) { error(_("starting year greater than ending year")); @@ -1335,8 +1355,6 @@ const char * const timep; } rp->r_yrtype = ecpyalloc(typep); } - if (rp->r_loyear < min_year && rp->r_loyear > 0) - min_year = rp->r_loyear; /* ** Day work. ** Accept things such as: @@ -1390,12 +1408,24 @@ const long val; char * const buf; { register int i; - register long shift; + register int shift; for (i = 0, shift = 24; i < 4; ++i, shift -= 8) buf[i] = val >> shift; } +static void +convert64(val, buf) +const zic_t val; +char * const buf; +{ + register int i; + register int shift; + + for (i = 0, shift = 56; i < 8; ++i, shift -= 8) + buf[i] = val >> shift; +} + static void puttzcode(val, fp) const long val; @@ -1407,28 +1437,50 @@ FILE * const fp; (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); } +static void +puttzcode64(val, fp) +const zic_t val; +FILE * const fp; +{ + char buf[8]; + + convert64(val, buf); + (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); +} + static int atcomp(avp, bvp) -void * avp; -void * bvp; +const void * avp; +const void * bvp; { - if (((struct attype *) avp)->at < ((struct attype *) bvp)->at) - return -1; - else if (((struct attype *) avp)->at > ((struct attype *) bvp)->at) - return 1; - else return 0; + const zic_t a = ((const struct attype *) avp)->at; + const zic_t b = ((const struct attype *) bvp)->at; + + return (a < b) ? -1 : (a > b); +} + +static int +is32(x) +const zic_t x; +{ + return INT32_MIN <= x && x <= INT32_MAX; } static void -writezone(name) +writezone(name, string) const char * const name; +const char * const string; { - register FILE * fp; - register int i, j; - static char * fullname; - static struct tzhead tzh; - time_t ats[TZ_MAX_TIMES]; - unsigned char types[TZ_MAX_TIMES]; + register FILE * fp; + register int i, j; + register int leapcnt32, leapi32; + register int timecnt32, timei32; + register int pass; + static char * fullname; + static const struct tzhead tzh0; + static struct tzhead tzh; + zic_t ats[TZ_MAX_TIMES]; + unsigned char types[TZ_MAX_TIMES]; /* ** Sort. @@ -1451,14 +1503,13 @@ const char * const name; while (fromi < timecnt && attypes[fromi].type == 0) ++fromi; /* handled by default rule */ for ( ; fromi < timecnt; ++fromi) { - if (toi != 0 - && ((attypes[fromi].at - + gmtoffs[attypes[toi - 1].type]) - <= (attypes[toi - 1].at - + gmtoffs[toi == 1 ? 0 - : attypes[toi - 2].type]))) { - attypes[toi - 1].type = attypes[fromi].type; - continue; + if (toi != 0 && ((attypes[fromi].at + + gmtoffs[attypes[toi - 1].type]) <= + (attypes[toi - 1].at + gmtoffs[toi == 1 ? 0 + : attypes[toi - 2].type]))) { + attypes[toi - 1].type = + attypes[fromi].type; + continue; } if (toi == 0 || attypes[toi - 1].type != attypes[fromi].type) @@ -1473,6 +1524,36 @@ const char * const name; ats[i] = attypes[i].at; types[i] = attypes[i].type; } + /* + ** Correct for leap seconds. + */ + for (i = 0; i < timecnt; ++i) { + j = leapcnt; + while (--j >= 0) + if (ats[i] > trans[j] - corr[j]) { + ats[i] = tadd(ats[i], corr[j]); + break; + } + } + /* + ** Figure out 32-bit-limited starts and counts. + */ + timecnt32 = timecnt; + timei32 = 0; + leapcnt32 = leapcnt; + leapi32 = 0; + while (timecnt32 > 0 && !is32(ats[timecnt32 - 1])) + --timecnt32; + while (timecnt32 > 0 && !is32(ats[timei32])) { + --timecnt32; + ++timei32; + } + while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1])) + --leapcnt32; + while (leapcnt32 > 0 && !is32(trans[leapi32])) { + --leapcnt32; + ++leapi32; + } fullname = erealloc(fullname, (int) (strlen(directory) + 1 + strlen(name) + 1)); (void) sprintf(fullname, "%s/%s", directory, name); @@ -1484,102 +1565,388 @@ const char * const name; (void) fprintf(stderr, _("%s: Can't remove %s: %s\n"), progname, fullname, e); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } if ((fp = fopen(fullname, "wb")) == NULL) { if (mkdirs(fullname) != 0) - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); if ((fp = fopen(fullname, "wb")) == NULL) { const char *e = strerror(errno); (void) fprintf(stderr, _("%s: Can't create %s: %s\n"), progname, fullname, e); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } } - convert(eitol(typecnt), tzh.tzh_ttisgmtcnt); - convert(eitol(typecnt), tzh.tzh_ttisstdcnt); - convert(eitol(leapcnt), tzh.tzh_leapcnt); - convert(eitol(timecnt), tzh.tzh_timecnt); - convert(eitol(typecnt), tzh.tzh_typecnt); - convert(eitol(charcnt), tzh.tzh_charcnt); - (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); -#define DO(field) (void) fwrite((void *) tzh.field, (size_t) sizeof tzh.field, (size_t) 1, fp) - DO(tzh_magic); - DO(tzh_reserved); - DO(tzh_ttisgmtcnt); - DO(tzh_ttisstdcnt); - DO(tzh_leapcnt); - DO(tzh_timecnt); - DO(tzh_typecnt); - DO(tzh_charcnt); + for (pass = 1; pass <= 2; ++pass) { + register int thistimei, thistimecnt; + register int thisleapi, thisleapcnt; + register int thistimelim, thisleaplim; + int writetype[TZ_MAX_TIMES]; + int typemap[TZ_MAX_TYPES]; + register int thistypecnt; + char thischars[TZ_MAX_CHARS]; + char thischarcnt; + int indmap[TZ_MAX_CHARS]; + + if (pass == 1) { + thistimei = timei32; + thistimecnt = timecnt32; + thisleapi = leapi32; + thisleapcnt = leapcnt32; + } else { + thistimei = 0; + thistimecnt = timecnt; + thisleapi = 0; + thisleapcnt = leapcnt; + } + thistimelim = thistimei + thistimecnt; + thisleaplim = thisleapi + thisleapcnt; + for (i = 0; i < typecnt; ++i) + writetype[i] = thistimecnt == timecnt; + if (thistimecnt == 0) { + /* + ** No transition times fall in the current + ** (32- or 64-bit) window. + */ + if (typecnt != 0) + writetype[typecnt - 1] = TRUE; + } else { + for (i = thistimei - 1; i < thistimelim; ++i) + if (i >= 0) + writetype[types[i]] = TRUE; + /* + ** For America/Godthab and Antarctica/Palmer + */ + if (thistimei == 0) + writetype[0] = TRUE; + } + thistypecnt = 0; + for (i = 0; i < typecnt; ++i) + typemap[i] = writetype[i] ? thistypecnt++ : -1; + for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i) + indmap[i] = -1; + thischarcnt = 0; + for (i = 0; i < typecnt; ++i) { + register char * thisabbr; + + if (!writetype[i]) + continue; + if (indmap[abbrinds[i]] >= 0) + continue; + thisabbr = &chars[abbrinds[i]]; + for (j = 0; j < thischarcnt; ++j) + if (strcmp(&thischars[j], thisabbr) == 0) + break; + if (j == thischarcnt) { + (void) strcpy(&thischars[(int) thischarcnt], + thisabbr); + thischarcnt += strlen(thisabbr) + 1; + } + indmap[abbrinds[i]] = j; + } +#define DO(field) (void) fwrite((void *) tzh.field, \ + (size_t) sizeof tzh.field, (size_t) 1, fp) + tzh = tzh0; + (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); + tzh.tzh_version[0] = ZIC_VERSION; + convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt); + convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt); + convert(eitol(thisleapcnt), tzh.tzh_leapcnt); + convert(eitol(thistimecnt), tzh.tzh_timecnt); + convert(eitol(thistypecnt), tzh.tzh_typecnt); + convert(eitol(thischarcnt), tzh.tzh_charcnt); + DO(tzh_magic); + DO(tzh_version); + DO(tzh_reserved); + DO(tzh_ttisgmtcnt); + DO(tzh_ttisstdcnt); + DO(tzh_leapcnt); + DO(tzh_timecnt); + DO(tzh_typecnt); + DO(tzh_charcnt); #undef DO - for (i = 0; i < timecnt; ++i) { - j = leapcnt; - while (--j >= 0) - if (ats[i] >= trans[j]) { - ats[i] = tadd(ats[i], corr[j]); - break; + for (i = thistimei; i < thistimelim; ++i) + if (pass == 1) + puttzcode((long) ats[i], fp); + else puttzcode64(ats[i], fp); + for (i = thistimei; i < thistimelim; ++i) { + unsigned char uc; + + uc = typemap[types[i]]; + (void) fwrite((void *) &uc, + (size_t) sizeof uc, + (size_t) 1, + fp); + } + for (i = 0; i < typecnt; ++i) + if (writetype[i]) { + puttzcode(gmtoffs[i], fp); + (void) putc(isdsts[i], fp); + (void) putc((unsigned char) indmap[abbrinds[i]], fp); } - puttzcode((long) ats[i], fp); + if (thischarcnt != 0) + (void) fwrite((void *) thischars, + (size_t) sizeof thischars[0], + (size_t) thischarcnt, fp); + for (i = thisleapi; i < thisleaplim; ++i) { + register zic_t todo; + + if (roll[i]) { + if (timecnt == 0 || trans[i] < ats[0]) { + j = 0; + while (isdsts[j]) + if (++j >= typecnt) { + j = 0; + break; + } + } else { + j = 1; + while (j < timecnt && + trans[i] >= ats[j]) + ++j; + j = types[j - 1]; + } + todo = tadd(trans[i], -gmtoffs[j]); + } else todo = trans[i]; + if (pass == 1) + puttzcode((long) todo, fp); + else puttzcode64(todo, fp); + puttzcode(corr[i], fp); + } + for (i = 0; i < typecnt; ++i) + if (writetype[i]) + (void) putc(ttisstds[i], fp); + for (i = 0; i < typecnt; ++i) + if (writetype[i]) + (void) putc(ttisgmts[i], fp); } - if (timecnt > 0) - (void) fwrite((void *) types, (size_t) sizeof types[0], - (size_t) timecnt, fp); - for (i = 0; i < typecnt; ++i) { - puttzcode((long) gmtoffs[i], fp); - (void) putc(isdsts[i], fp); - (void) putc(abbrinds[i], fp); - } - if (charcnt != 0) - (void) fwrite((void *) chars, (size_t) sizeof chars[0], - (size_t) charcnt, fp); - for (i = 0; i < leapcnt; ++i) { - if (roll[i]) { - if (timecnt == 0 || trans[i] < ats[0]) { - j = 0; - while (isdsts[j]) - if (++j >= typecnt) { - j = 0; - break; - } - } else { - j = 1; - while (j < timecnt && trans[i] >= ats[j]) - ++j; - j = types[j - 1]; - } - puttzcode((long) tadd(trans[i], -gmtoffs[j]), fp); - } else puttzcode((long) trans[i], fp); - puttzcode((long) corr[i], fp); - } - for (i = 0; i < typecnt; ++i) - (void) putc(ttisstds[i], fp); - for (i = 0; i < typecnt; ++i) - (void) putc(ttisgmts[i], fp); + (void) fprintf(fp, "\n%s\n", string); if (ferror(fp) || fclose(fp)) { (void) fprintf(stderr, _("%s: Error writing %s\n"), progname, fullname); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } } static void -doabbr(abbr, format, letters, isdst) +doabbr(abbr, format, letters, isdst, doquotes) char * const abbr; const char * const format; const char * const letters; const int isdst; +const int doquotes; { - if (strchr(format, '/') == NULL) { + register char * cp; + register char * slashp; + register int len; + + slashp = strchr(format, '/'); + if (slashp == NULL) { if (letters == NULL) (void) strcpy(abbr, format); else (void) sprintf(abbr, format, letters); - } else if (isdst) - (void) strcpy(abbr, strchr(format, '/') + 1); - else { - (void) strcpy(abbr, format); - *strchr(abbr, '/') = '\0'; + } else if (isdst) { + (void) strcpy(abbr, slashp + 1); + } else { + if (slashp > format) + (void) strncpy(abbr, format, + (unsigned) (slashp - format)); + abbr[slashp - format] = '\0'; + } + if (!doquotes) + return; + for (cp = abbr; *cp != '\0'; ++cp) + if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *cp) == NULL && + strchr("abcdefghijklmnopqrstuvwxyz", *cp) == NULL) + break; + len = strlen(abbr); + if (len > 0 && *cp == '\0') + return; + abbr[len + 2] = '\0'; + abbr[len + 1] = '>'; + for ( ; len > 0; --len) + abbr[len] = abbr[len - 1]; + abbr[0] = '<'; +} + +static void +updateminmax(x) +const int x; +{ + if (min_year > x) + min_year = x; + if (max_year < x) + max_year = x; +} + +static int +stringoffset(result, offset) +char * result; +long offset; +{ + register int hours; + register int minutes; + register int seconds; + + result[0] = '\0'; + if (offset < 0) { + (void) strcpy(result, "-"); + offset = -offset; + } + seconds = offset % SECSPERMIN; + offset /= SECSPERMIN; + minutes = offset % MINSPERHOUR; + offset /= MINSPERHOUR; + hours = offset; + if (hours >= HOURSPERDAY) { + result[0] = '\0'; + return -1; + } + (void) sprintf(end(result), "%d", hours); + if (minutes != 0 || seconds != 0) { + (void) sprintf(end(result), ":%02d", minutes); + if (seconds != 0) + (void) sprintf(end(result), ":%02d", seconds); + } + return 0; +} + +static int +stringrule(result, rp, dstoff, gmtoff) +char * result; +const struct rule * const rp; +const long dstoff; +const long gmtoff; +{ + register long tod; + + result = end(result); + if (rp->r_dycode == DC_DOM) { + register int month, total; + + if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY) + return -1; + total = 0; + for (month = 0; month < rp->r_month; ++month) + total += len_months[0][month]; + (void) sprintf(result, "J%d", total + rp->r_dayofmonth); + } else { + register int week; + + if (rp->r_dycode == DC_DOWGEQ) { + week = 1 + rp->r_dayofmonth / DAYSPERWEEK; + if ((week - 1) * DAYSPERWEEK + 1 != rp->r_dayofmonth) + return -1; + } else if (rp->r_dycode == DC_DOWLEQ) { + if (rp->r_dayofmonth == len_months[1][rp->r_month]) + week = 5; + else { + week = 1 + rp->r_dayofmonth / DAYSPERWEEK; + if (week * DAYSPERWEEK - 1 != rp->r_dayofmonth) + return -1; + } + } else return -1; /* "cannot happen" */ + (void) sprintf(result, "M%d.%d.%d", + rp->r_month + 1, week, rp->r_wday); + } + tod = rp->r_tod; + if (rp->r_todisgmt) + tod += gmtoff; + if (rp->r_todisstd && rp->r_stdoff == 0) + tod += dstoff; + if (tod < 0) { + result[0] = '\0'; + return -1; + } + if (tod != 2 * SECSPERMIN * MINSPERHOUR) { + (void) strcat(result, "/"); + if (stringoffset(end(result), tod) != 0) + return -1; + } + return 0; +} + +static void +stringzone(result, zpfirst, zonecount) +char * result; +const struct zone * const zpfirst; +const int zonecount; +{ + register const struct zone * zp; + register struct rule * rp; + register struct rule * stdrp; + register struct rule * dstrp; + register int i; + register const char * abbrvar; + + result[0] = '\0'; + zp = zpfirst + zonecount - 1; + stdrp = dstrp = NULL; + for (i = 0; i < zp->z_nrules; ++i) { + rp = &zp->z_rules[i]; + if (rp->r_hiwasnum || rp->r_hiyear != INT_MAX) + continue; + if (rp->r_yrtype != NULL) + continue; + if (rp->r_stdoff == 0) { + if (stdrp == NULL) + stdrp = rp; + else return; + } else { + if (dstrp == NULL) + dstrp = rp; + else return; + } + } + if (stdrp == NULL && dstrp == NULL) { + /* + ** There are no rules running through "max". + ** Let's find the latest rule. + */ + for (i = 0; i < zp->z_nrules; ++i) { + rp = &zp->z_rules[i]; + if (stdrp == NULL || rp->r_hiyear > stdrp->r_hiyear || + (rp->r_hiyear == stdrp->r_hiyear && + rp->r_month > stdrp->r_month)) + stdrp = rp; + } + if (stdrp != NULL && stdrp->r_stdoff != 0) + return; /* We end up in DST (a POSIX no-no). */ + /* + ** Horrid special case: if year is 2037, + ** presume this is a zone handled on a year-by-year basis; + ** do not try to apply a rule to the zone. + */ + if (stdrp != NULL && stdrp->r_hiyear == 2037) + return; + } + if (stdrp == NULL && zp->z_nrules != 0) + return; + abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar; + doabbr(result, zp->z_format, abbrvar, FALSE, TRUE); + if (stringoffset(end(result), -zp->z_gmtoff) != 0) { + result[0] = '\0'; + return; + } + if (dstrp == NULL) + return; + doabbr(end(result), zp->z_format, dstrp->r_abbrvar, TRUE, TRUE); + if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR) + if (stringoffset(end(result), + -(zp->z_gmtoff + dstrp->r_stdoff)) != 0) { + result[0] = '\0'; + return; + } + (void) strcat(result, ","); + if (stringrule(result, dstrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) { + result[0] = '\0'; + return; + } + (void) strcat(result, ","); + if (stringrule(result, stdrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) { + result[0] = '\0'; + return; } } @@ -1592,7 +1959,7 @@ const int zonecount; register struct rule * rp; register int i, j; register int usestart, useuntil; - register time_t starttime, untiltime; + register zic_t starttime, untiltime; register long gmtoff; register long stdoff; register int year; @@ -1600,8 +1967,17 @@ const int zonecount; register int startttisstd; register int startttisgmt; register int type; - char startbuf[BUFSIZ]; + register char * startbuf; + register char * ab; + register char * envvar; + register int max_abbr_len; + register int max_envvar_len; + max_abbr_len = 2 + max_format_len + max_abbrvar_len; + max_envvar_len = 2 * max_abbr_len + 5 * 9; + startbuf = emalloc(max_abbr_len + 1); + ab = emalloc(max_abbr_len + 1); + envvar = emalloc(max_envvar_len + 1); INITIALIZE(untiltime); INITIALIZE(starttime); /* @@ -1611,11 +1987,57 @@ const int zonecount; typecnt = 0; charcnt = 0; /* - ** Thanks to Earl Chew (earl@dnd.icp.nec.com.au) + ** Thanks to Earl Chew ** for noting the need to unconditionally initialize startttisstd. */ startttisstd = FALSE; startttisgmt = FALSE; + min_year = max_year = EPOCH_YEAR; + if (leapseen) { + updateminmax(leapminyear); + updateminmax(leapmaxyear + (leapmaxyear < INT_MAX)); + } + for (i = 0; i < zonecount; ++i) { + zp = &zpfirst[i]; + if (i < zonecount - 1) + updateminmax(zp->z_untilrule.r_loyear); + for (j = 0; j < zp->z_nrules; ++j) { + rp = &zp->z_rules[j]; + if (rp->r_lowasnum) + updateminmax(rp->r_loyear); + if (rp->r_hiwasnum) + updateminmax(rp->r_hiyear); + } + } + /* + ** Generate lots of data if a rule can't cover all future times. + */ + stringzone(envvar, zpfirst, zonecount); + if (noise && envvar[0] == '\0') { + register char * wp; + +wp = ecpyalloc(_("no POSIX environment variable for zone")); + wp = ecatalloc(wp, " "); + wp = ecatalloc(wp, zpfirst->z_name); + warning(wp); + ifree(wp); + } + if (envvar[0] == '\0') { + if (min_year >= INT_MIN + YEARSPERREPEAT) + min_year -= YEARSPERREPEAT; + else min_year = INT_MIN; + if (max_year <= INT_MAX - YEARSPERREPEAT) + max_year += YEARSPERREPEAT; + else max_year = INT_MAX; + } + /* + ** For the benefit of older systems, + ** generate data from 1900 through 2037. + */ + if (min_year > 1900) + min_year = 1900; + if (max_year < 2037) + max_year = 2037; for (i = 0; i < zonecount; ++i) { /* ** A guess that may well be corrected later. @@ -1633,7 +2055,7 @@ const int zonecount; if (zp->z_nrules == 0) { stdoff = zp->z_stdoff; doabbr(startbuf, zp->z_format, - (char *) NULL, stdoff != 0); + (char *) NULL, stdoff != 0, FALSE); type = addtype(oadd(zp->z_gmtoff, stdoff), startbuf, stdoff != 0, startttisstd, startttisgmt); @@ -1661,9 +2083,8 @@ const int zonecount; } for ( ; ; ) { register int k; - register time_t jtime, ktime; + register zic_t jtime, ktime; register long offset; - char buf[BUFSIZ]; INITIALIZE(ktime); if (useuntil) { @@ -1719,23 +2140,27 @@ const int zonecount; stdoff); doabbr(startbuf, zp->z_format, rp->r_abbrvar, - rp->r_stdoff != 0); + rp->r_stdoff != 0, + FALSE); continue; } if (*startbuf == '\0' && - startoff == oadd(zp->z_gmtoff, - stdoff)) { - doabbr(startbuf, zp->z_format, - rp->r_abbrvar, - rp->r_stdoff != 0); + startoff == oadd(zp->z_gmtoff, + stdoff)) { + doabbr(startbuf, + zp->z_format, + rp->r_abbrvar, + rp->r_stdoff != + 0, + FALSE); } } eats(zp->z_filename, zp->z_linenum, rp->r_filename, rp->r_linenum); - doabbr(buf, zp->z_format, rp->r_abbrvar, - rp->r_stdoff != 0); + doabbr(ab, zp->z_format, rp->r_abbrvar, + rp->r_stdoff != 0, FALSE); offset = oadd(zp->z_gmtoff, rp->r_stdoff); - type = addtype(offset, buf, rp->r_stdoff != 0, + type = addtype(offset, ab, rp->r_stdoff != 0, rp->r_todisstd, rp->r_todisgmt); addtt(ktime, type); } @@ -1768,12 +2193,15 @@ error(_("can't determine time zone abbreviation to use just after until time")); starttime = tadd(starttime, -gmtoff); } } - writezone(zpfirst->z_name); + writezone(zpfirst->z_name, envvar); + ifree(startbuf); + ifree(ab); + ifree(envvar); } static void addtt(starttime, type) -const time_t starttime; +const zic_t starttime; int type; { if (starttime <= min_time || @@ -1792,7 +2220,7 @@ int type; } if (timecnt >= TZ_MAX_TIMES) { error(_("too many transitions?!")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } attypes[timecnt].at = starttime; attypes[timecnt].type = type; @@ -1811,15 +2239,15 @@ const int ttisgmt; if (isdst != TRUE && isdst != FALSE) { error(_("internal error - addtype called with bad isdst")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } if (ttisstd != TRUE && ttisstd != FALSE) { error(_("internal error - addtype called with bad ttisstd")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } if (ttisgmt != TRUE && ttisgmt != FALSE) { error(_("internal error - addtype called with bad ttisgmt")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } /* ** See if there's already an entry for this zone type. @@ -1838,7 +2266,11 @@ const int ttisgmt; */ if (typecnt >= TZ_MAX_TYPES) { error(_("too many local time types")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); + } + if (! (-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) { + error(_("UTC offset out of range")); + exit(EXIT_FAILURE); } gmtoffs[i] = gmtoff; isdsts[i] = isdst; @@ -1857,7 +2289,7 @@ const int ttisgmt; static void leapadd(t, positive, rolling, count) -const time_t t; +const zic_t t; const int positive; const int rolling; int count; @@ -1866,13 +2298,13 @@ int count; if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) { error(_("too many leap seconds")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } for (i = 0; i < leapcnt; ++i) if (t <= trans[i]) { if (t == trans[i]) { error(_("repeated leap second moment")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } break; } @@ -1890,7 +2322,7 @@ int count; } static void -adjleap P((void)) +adjleap(void) { register int i; register long last = 0; @@ -1927,7 +2359,7 @@ const char * const type; (void) fprintf(stderr, _("%s: command was '%s', result was %d\n"), progname, buf, result); for ( ; ; ) - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } static int @@ -2008,8 +2440,9 @@ register char * cp; emalloc((int) ((strlen(cp) + 1) * sizeof *array)); nsubs = 0; for ( ; ; ) { - while (isascii(*cp) && isspace((unsigned char) *cp)) - ++cp; + while (isascii((unsigned char) *cp) && + isspace((unsigned char) *cp)) + ++cp; if (*cp == '\0' || *cp == '#') break; array[nsubs++] = dp = cp; @@ -2019,7 +2452,12 @@ register char * cp; else while ((*dp = *cp++) != '"') if (*dp != '\0') ++dp; - else error(_("Odd number of quotation marks")); + else { + error(_( + "Odd number of quotation marks" + )); + exit(1); + } } while (*cp != '\0' && *cp != '#' && (!isascii(*cp) || !isspace((unsigned char) *cp))); if (isascii(*cp) && isspace((unsigned char) *cp)) @@ -2040,17 +2478,17 @@ const long t2; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { error(_("time overflow")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } return t; } -static time_t +static zic_t tadd(t1, t2) -const time_t t1; +const zic_t t1; const long t2; { - register time_t t; + register zic_t t; if (t1 == max_time && t2 > 0) return max_time; @@ -2059,7 +2497,7 @@ const long t2; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { error(_("time overflow")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } return t; } @@ -2069,14 +2507,14 @@ const long t2; ** 1970, 00:00 LOCAL time - in that year that the rule refers to. */ -static time_t +static zic_t rpytime(rp, wantedy) register const struct rule * const rp; register const int wantedy; { register int y, m, i; register long dayoff; /* with a nod to Margaret O. */ - register time_t t; + register zic_t t; if (wantedy == INT_MIN) return min_time; @@ -2106,7 +2544,7 @@ register const int wantedy; --i; else { error(_("use of 2/29 in non leap-year")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } } --i; @@ -2140,16 +2578,15 @@ register const int wantedy; } if (i < 0 || i >= len_months[isleap(y)][m]) { if (noise) - warning(_("rule goes past start/end of month--will not work with pre-2004 versions of zic")); + warning(_("rule goes past start/end of month--\ +will not work with pre-2004 versions of zic")); } } - if (dayoff < 0 && !TYPE_SIGNED(time_t)) - return min_time; if (dayoff < min_time / SECSPERDAY) return min_time; if (dayoff > max_time / SECSPERDAY) return max_time; - t = (time_t) dayoff * SECSPERDAY; + t = (zic_t) dayoff * SECSPERDAY; return tadd(t, rp->r_tod); } @@ -2159,10 +2596,48 @@ const char * const string; { register int i; + if (strcmp(string, GRANDPARENTED) != 0) { + register const char * cp; + register char * wp; + + /* + ** Want one to ZIC_MAX_ABBR_LEN_WO_WARN alphabetics + ** optionally followed by a + or - and a number from 1 to 14. + */ + cp = string; + wp = NULL; + while (isascii((unsigned char) *cp) && + isalpha((unsigned char) *cp)) + ++cp; + if (cp - string == 0) +wp = _("time zone abbreviation lacks alphabetic at start"); + if (noise && cp - string > 3) +wp = _("time zone abbreviation has more than 3 alphabetics"); + if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN) +wp = _("time zone abbreviation has too many alphabetics"); + if (wp == NULL && (*cp == '+' || *cp == '-')) { + ++cp; + if (isascii((unsigned char) *cp) && + isdigit((unsigned char) *cp)) + if (*cp++ == '1' && + *cp >= '0' && *cp <= '4') + ++cp; + } + if (*cp != '\0') +wp = _("time zone abbreviation differs from POSIX standard"); + if (wp != NULL) { + wp = ecpyalloc(wp); + wp = ecatalloc(wp, " ("); + wp = ecatalloc(wp, string); + wp = ecatalloc(wp, ")"); + warning(wp); + ifree(wp); + } + } i = strlen(string) + 1; if (charcnt + i > TZ_MAX_CHARS) { error(_("too many, or too long, time zone abbreviations")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } (void) strcpy(&chars[charcnt], string); charcnt += eitol(i); @@ -2170,7 +2645,7 @@ const char * const string; static int mkdirs(argname) -char * const argname; +char * argname; { register char * name; register char * cp; @@ -2226,7 +2701,7 @@ const int i; (void) fprintf(stderr, _("%s: %d did not sign extend correctly\n"), progname, i); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } return l; }