summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1996-07-18 18:53:15 +0000
committerwollman <wollman@FreeBSD.org>1996-07-18 18:53:15 +0000
commitf90be6962ca389a2fdd417fedfda651caaafe55b (patch)
treeb6478e67c004577a191e133e676433c80465a1e5
parentc79e9e34b5daad1ba280439b95ec4d08843ea517 (diff)
downloadFreeBSD-src-f90be6962ca389a2fdd417fedfda651caaafe55b.zip
FreeBSD-src-f90be6962ca389a2fdd417fedfda651caaafe55b.tar.gz
Merge the recently-imported tzcode96h distribution (libc portion). The
part that does zic(8)/zdump(8) is still yet to be imported (but the old zic and zdump will work just fine with these header files and the data format has not changed).
-rw-r--r--lib/libc/stdtime/asctime.c6
-rw-r--r--lib/libc/stdtime/difftime.c15
-rw-r--r--lib/libc/stdtime/localtime.c115
-rw-r--r--lib/libc/stdtime/private.h108
-rw-r--r--lib/libc/stdtime/strftime.c190
-rw-r--r--lib/libc/stdtime/tzfile.h13
6 files changed, 254 insertions, 193 deletions
diff --git a/lib/libc/stdtime/asctime.c b/lib/libc/stdtime/asctime.c
index 1655f6a..a1834b6 100644
--- a/lib/libc/stdtime/asctime.c
+++ b/lib/libc/stdtime/asctime.c
@@ -1,7 +1,11 @@
+/*
+** This file is in the public domain, so clarified as of
+** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
+*/
#ifndef lint
#ifndef NOID
-static char elsieid[] = "@(#)asctime.c 7.5";
+static char elsieid[] = "@(#)asctime.c 7.7";
#endif /* !defined NOID */
#endif /* !defined lint */
diff --git a/lib/libc/stdtime/difftime.c b/lib/libc/stdtime/difftime.c
index c8cd286..f178524 100644
--- a/lib/libc/stdtime/difftime.c
+++ b/lib/libc/stdtime/difftime.c
@@ -1,8 +1,11 @@
-
+/*
+** This file is in the public domain, so clarified as of
+** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
+*/
#ifndef lint
#ifndef NOID
-static char elsieid[] = "@(#)difftime.c 7.4";
+static char elsieid[] = "@(#)difftime.c 7.7";
#endif /* !defined NOID */
#endif /* !defined lint */
@@ -45,9 +48,7 @@ const time_t time0;
/*
** Repair delta overflow.
*/
- hibit = 1;
- while ((hibit <<= 1) > 0)
- continue;
+ hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1);
/*
** The following expression rounds twice, which means
** the result may not be the closest to the true answer.
@@ -67,10 +68,10 @@ const time_t time0;
** This problem occurs only with very large differences.
** It's too painful to fix this portably.
** We are not alone in this problem;
- ** many C compilers round twice when converting
+ ** 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.
+ ** has the same double-rounding problem with those compilers.
*/
return delta - 2 * (long_double) hibit;
}
diff --git a/lib/libc/stdtime/localtime.c b/lib/libc/stdtime/localtime.c
index c4cfc88..ecb201b 100644
--- a/lib/libc/stdtime/localtime.c
+++ b/lib/libc/stdtime/localtime.c
@@ -1,8 +1,11 @@
-
+/*
+** This file is in the public domain, so clarified as of
+** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
+*/
#ifndef lint
#ifndef NOID
-static char elsieid[] = "@(#)localtime.c 7.44";
+static char elsieid[] = "@(#)localtime.c 7.57";
#endif /* !defined NOID */
#endif /* !defined lint */
@@ -200,7 +203,7 @@ const char * const codep;
register long result;
register int i;
- result = (codep[0] & 0x80) ? ~0L : 0L;
+ result = (codep[0] & 0x80) ? ~0L : 0L;
for (i = 0; i < 4; ++i)
result = (result << 8) | (codep[i] & 0xff);
return result;
@@ -209,8 +212,8 @@ const char * const codep;
static void
settzname P((void))
{
- register struct state * const sp = lclptr;
- register int i;
+ register struct state * const sp = lclptr;
+ register int i;
tzname[0] = wildabbr;
tzname[1] = wildabbr;
@@ -425,7 +428,7 @@ register const char * strp;
{
register char c;
- while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' &&
+ while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
c != '+')
++strp;
return strp;
@@ -448,15 +451,15 @@ const int max;
register char c;
register int num;
- if (strp == NULL || !isdigit(*strp))
+ if (strp == NULL || !is_digit(c = *strp))
return NULL;
num = 0;
- while ((c = *strp) != '\0' && isdigit(c)) {
+ do {
num = num * 10 + (c - '0');
if (num > max)
return NULL; /* illegal value */
- ++strp;
- }
+ c = *++strp;
+ } while (is_digit(c));
if (num < min)
return NULL; /* illegal value */
*nump = num;
@@ -518,14 +521,13 @@ getoffset(strp, offsetp)
register const char * strp;
long * const offsetp;
{
- register int neg;
+ register int neg = 0;
if (*strp == '-') {
neg = 1;
++strp;
- } else if (isdigit(*strp) || *strp++ == '+')
- neg = 0;
- else return NULL; /* illegal offset */
+ } else if (*strp == '+')
+ ++strp;
strp = getsecs(strp, offsetp);
if (strp == NULL)
return NULL; /* illegal time */
@@ -570,7 +572,7 @@ register struct rule * const rulep;
if (*strp++ != '.')
return NULL;
strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
- } else if (isdigit(*strp)) {
+ } else if (is_digit(*strp)) {
/*
** Day of year.
*/
@@ -812,7 +814,8 @@ const int lastditch;
for (i = 0; i < sp->timecnt; ++i) {
j = sp->types[i];
if (!sp->ttis[j].tt_isdst) {
- theirstdoffset = -sp->ttis[j].tt_gmtoff;
+ theirstdoffset =
+ -sp->ttis[j].tt_gmtoff;
break;
}
}
@@ -820,7 +823,8 @@ const int lastditch;
for (i = 0; i < sp->timecnt; ++i) {
j = sp->types[i];
if (sp->ttis[j].tt_isdst) {
- theirdstoffset = -sp->ttis[j].tt_gmtoff;
+ theirdstoffset =
+ -sp->ttis[j].tt_gmtoff;
break;
}
}
@@ -1284,30 +1288,27 @@ register struct tm * const tmp;
tmp->tm_hour = (int) (rem / SECSPERHOUR);
rem = rem % SECSPERHOUR;
tmp->tm_min = (int) (rem / SECSPERMIN);
- tmp->tm_sec = (int) (rem % SECSPERMIN);
- if (hit)
- /*
- ** A positive leap second requires a special
- ** representation. This uses "... ??:59:60" et seq.
- */
- tmp->tm_sec += hit;
+ /*
+ ** A positive leap second requires a special
+ ** 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;
- if (days >= 0)
- for ( ; ; ) {
- yleap = isleap(y);
- if (days < (long) year_lengths[yleap])
- break;
- ++y;
- days = days - (long) year_lengths[yleap];
- }
- else do {
- --y;
- yleap = isleap(y);
- days = days + (long) year_lengths[yleap];
- } while (days < 0);
+#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];
@@ -1336,7 +1337,8 @@ const time_t * const timep;
/*
** 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. (mtxinu!kridle now).
+** 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
** just 32 bits, its a max of 32 iterations (even at 64 bits it
** would still be very reasonable).
@@ -1426,10 +1428,12 @@ int * const okayp;
while (yourtm.tm_mday <= 0) {
if (increment_overflow(&yourtm.tm_year, -1))
return WRONG;
- yourtm.tm_mday += year_lengths[isleap(yourtm.tm_year)];
+ i = yourtm.tm_year + (1 < yourtm.tm_mon);
+ yourtm.tm_mday += year_lengths[isleap(i)];
}
while (yourtm.tm_mday > DAYSPERLYEAR) {
- yourtm.tm_mday -= year_lengths[isleap(yourtm.tm_year)];
+ i = yourtm.tm_year + (1 < yourtm.tm_mon);
+ yourtm.tm_mday -= year_lengths[isleap(i)];
if (increment_overflow(&yourtm.tm_year, 1))
return WRONG;
}
@@ -1464,17 +1468,16 @@ int * const okayp;
yourtm.tm_sec = 0;
}
/*
- ** Calculate the number of magnitude bits in a time_t
- ** (this works regardless of whether time_t is
- ** signed or unsigned, though lint complains if unsigned).
+ ** Divide the search space in half
+ ** (this works whether time_t is signed or unsigned).
*/
- for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
- continue;
+ bits = TYPE_BIT(time_t) - 1;
/*
- ** If time_t is signed, then 0 is the median value,
- ** if time_t is unsigned, then 1 << bits is median.
+ ** 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 = (t < 0) ? 0 : ((time_t) 1 << bits);
+ t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits);
for ( ; ; ) {
(*funcp)(&t, offset, &mytm);
dir = tmcomp(&mytm, &yourtm);
@@ -1482,10 +1485,10 @@ int * const okayp;
if (bits-- < 0)
return WRONG;
if (bits < 0)
- --t;
+ --t; /* may be needed if new t is minimal */
else if (dir > 0)
- t -= (time_t) 1 << bits;
- else t += (time_t) 1 << bits;
+ t -= ((time_t) 1) << bits;
+ else t += ((time_t) 1) << bits;
continue;
}
if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
@@ -1506,10 +1509,10 @@ int * const okayp;
if (sp == NULL)
return WRONG;
#endif /* defined ALL_STATE */
- for (i = 0; i < sp->typecnt; ++i) {
+ for (i = sp->typecnt - 1; i >= 0; --i) {
if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
continue;
- for (j = 0; j < sp->typecnt; ++j) {
+ for (j = sp->typecnt - 1; j >= 0; --j) {
if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
continue;
newt = t + sp->ttis[j].tt_gmtoff -
@@ -1541,7 +1544,7 @@ label:
static time_t
time1(tmp, funcp, offset)
struct tm * const tmp;
-void (* const funcp) P((const time_t*, long, struct tm*));
+void (* const funcp) P((const time_t *, long, struct tm *));
const long offset;
{
register time_t t;
@@ -1580,10 +1583,10 @@ const long offset;
if (sp == NULL)
return WRONG;
#endif /* defined ALL_STATE */
- for (samei = 0; samei < sp->typecnt; ++samei) {
+ for (samei = sp->typecnt - 1; samei >= 0; --samei) {
if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
continue;
- for (otheri = 0; otheri < sp->typecnt; ++otheri) {
+ for (otheri = sp->typecnt - 1; otheri >= 0; --otheri) {
if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
continue;
tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
diff --git a/lib/libc/stdtime/private.h b/lib/libc/stdtime/private.h
index 83d76f1..d8fa906 100644
--- a/lib/libc/stdtime/private.h
+++ b/lib/libc/stdtime/private.h
@@ -1,8 +1,10 @@
-
-
#ifndef PRIVATE_H
#define PRIVATE_H
+/*
+** This file is in the public domain, so clarified as of
+** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
+*/
/* Stuff moved from Makefile.inc to reduce clutter */
#ifndef TM_GMTOFF
@@ -11,6 +13,9 @@
#define STD_INSPIRED 1
#define PCTS 1
#define HAVE_LONG_DOUBLE 1
+#define HAVE_STRERROR 1
+#define HAVE_UNISTD_H 1
+#define LOCALE_HOME _PATH_LOCALE
#define TZDIR "/usr/share/zoneinfo"
#endif /* ndef TM_GMTOFF */
@@ -28,7 +33,9 @@
#ifndef lint
#ifndef NOID
-/*static char privatehid[] = "@(#)private.h 7.33";*/
+/*
+static char privatehid[] = "@(#)private.h 7.43";
+*/
#endif /* !defined NOID */
#endif /* !defined lint */
@@ -41,27 +48,46 @@
#define HAVE_ADJTIME 1
#endif /* !defined HAVE_ADJTIME */
+#ifndef HAVE_GETTEXT
+#define HAVE_GETTEXT 0
+#endif /* !defined HAVE_GETTEXT */
+
#ifndef HAVE_SETTIMEOFDAY
#define HAVE_SETTIMEOFDAY 3
#endif /* !defined HAVE_SETTIMEOFDAY */
+#ifndef HAVE_STRERROR
+#define HAVE_STRERROR 0
+#endif /* !defined HAVE_STRERROR */
+
#ifndef HAVE_UNISTD_H
#define HAVE_UNISTD_H 1
#endif /* !defined HAVE_UNISTD_H */
+#ifndef HAVE_UTMPX_H
+#define HAVE_UTMPX_H 0
+#endif /* !defined HAVE_UTMPX_H */
+
+#ifndef LOCALE_HOME
+#define LOCALE_HOME "/usr/lib/locale"
+#endif /* !defined LOCALE_HOME */
+
/*
** Nested includes
*/
#include "sys/types.h" /* for time_t */
#include "stdio.h"
-#include "ctype.h"
#include "errno.h"
#include "string.h"
#include "limits.h" /* for CHAR_BIT */
#include "time.h"
#include "stdlib.h"
+#if HAVE_GETTEXT - 0
+#include "libintl.h"
+#endif /* HAVE_GETTEXT - 0 */
+
#if HAVE_UNISTD_H - 0
#include "unistd.h" /* for F_OK and R_OK */
#endif /* HAVE_UNISTD_H - 0 */
@@ -75,22 +101,11 @@
#endif /* !defined R_OK */
#endif /* !(HAVE_UNISTD_H - 0) */
-/*
-** Workarounds for compilers/systems.
-*/
-
-/*
-** SunOS 4.1.1 cc lacks const.
-*/
-
-#ifndef const
-#ifndef __STDC__
-#define const
-#endif /* !defined __STDC__ */
-#endif /* !defined const */
+/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
+#define is_digit(c) ((unsigned)(c) - '0' <= 9)
/*
-** SunOS 4.1.1 cc lacks prototypes.
+** Workarounds for compilers/systems.
*/
#ifndef P
@@ -103,22 +118,6 @@
#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.
*/
@@ -140,15 +139,6 @@
#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 */
-
-/*
** Finally, some convenience items.
*/
@@ -160,15 +150,23 @@ extern int unlink P((const char * filename));
#define FALSE 0
#endif /* !defined FALSE */
+#ifndef TYPE_BIT
+#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
+#endif /* !defined TYPE_BIT */
+
+#ifndef TYPE_SIGNED
+#define TYPE_SIGNED(type) (((type) -1) < 0)
+#endif /* !defined TYPE_SIGNED */
+
#ifndef INT_STRLEN_MAXIMUM
/*
** 302 / 1000 is log10(2.0) rounded up.
-** Subtract one for the sign bit;
+** Subtract one for the sign bit if the type is signed;
** add one for integer division truncation;
-** add one more for a minus sign.
+** add one more for a minus sign if the type is signed.
*/
#define INT_STRLEN_MAXIMUM(type) \
- ((sizeof(type) * CHAR_BIT - 1) * 302 / 1000 + 2)
+ ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 100 + 1 + TYPE_SIGNED(type))
#endif /* !defined INT_STRLEN_MAXIMUM */
/*
@@ -196,6 +194,24 @@ extern int unlink P((const char * filename));
#endif /* !defined INITIALIZE */
/*
+** For the benefit of GNU folk...
+** `_(MSGID)' uses the current locale's message library string for MSGID.
+** The default is to use gettext if available, and use MSGID otherwise.
+*/
+
+#ifndef _
+#if HAVE_GETTEXT - 0
+#define _(msgid) gettext(msgid)
+#else /* !(HAVE_GETTEXT - 0) */
+#define _(msgid) msgid
+#endif /* !(HAVE_GETTEXT - 0) */
+#endif /* !defined _ */
+
+#ifndef TZ_DOMAIN
+#define TZ_DOMAIN "tz"
+#endif /* !defined TZ_DOMAIN */
+
+/*
** UNIX was a registered trademark of UNIX System Laboratories in 1993.
*/
diff --git a/lib/libc/stdtime/strftime.c b/lib/libc/stdtime/strftime.c
index 5e272be..4bb0ebd 100644
--- a/lib/libc/stdtime/strftime.c
+++ b/lib/libc/stdtime/strftime.c
@@ -17,12 +17,14 @@
#ifdef LIBC_RCS
static const char rcsid[] =
- "$Id: strftime.c,v 1.8 1996/05/27 06:54:01 scrappy Exp $";
+ "$Id: strftime.c,v 1.9 1996/07/12 18:55:32 jkh Exp $";
#endif
#ifndef lint
#ifndef NOID
-static const char elsieid[] = "@(#)strftime.c 7.38";
+/*
+static char elsieid[] = "@(#)strftime.c 7.47";
+*/
/*
** Based on the UCB version with the ID appearing below.
** This is ANSIish only when "multibyte character == plain character".
@@ -44,8 +46,6 @@ static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89";
#include <rune.h> /* for _PATH_LOCALE */
#include <sys/stat.h>
-#define LOCALE_HOME _PATH_LOCALE
-
struct lc_time_T {
const char * mon[12];
const char * month[12];
@@ -92,12 +92,12 @@ static const struct lc_time_T C_time_locale = {
"%m/%d/%y",
/*
- ** c_fmt (ctime-compatible)
+ ** c_fmt
** Note that
** "%a %b %d %H:%M:%S %Y"
** is used by Solaris 2.3.
*/
- "%a %b %e %X %Y",
+ "%D %X", /* %m/%d/%y %H:%M:%S */
/* am */
"AM",
@@ -106,13 +106,12 @@ static const struct lc_time_T C_time_locale = {
"PM",
/* date_fmt */
- "%a %b %e %X %Z %Y"
+ "%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 *));
-static char * _secs P((const struct tm *, char *, const char *));
size_t strftime P((char *, size_t, const char *, const struct tm *));
@@ -120,12 +119,12 @@ extern char * tzname[];
size_t
strftime(s, maxsize, format, t)
- char *const s;
- const size_t maxsize;
- const char *const format;
- const struct tm *const t;
+char * const s;
+const size_t maxsize;
+const char * const format;
+const struct tm * const t;
{
- char *p;
+ char * p;
tzset();
p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize);
@@ -137,10 +136,10 @@ strftime(s, maxsize, format, t)
static char *
_fmt(format, t, pt, ptlim)
- const char *format;
- const struct tm *const t;
- char *pt;
- const char *const ptlim;
+const char * format;
+const struct tm * const t;
+char * pt;
+const char * const ptlim;
{
for ( ; *format; ++format) {
if (*format == '%') {
@@ -278,7 +277,21 @@ label:
pt = _conv(t->tm_sec, "%02d", pt, ptlim);
continue;
case 's':
- pt = _secs(t, pt, ptlim);
+ {
+ struct tm tm;
+ char buf[INT_STRLEN_MAXIMUM(
+ time_t) + 1];
+ time_t mkt;
+
+ tm = *t;
+ mkt = mktime(&tm);
+ if (TYPE_SIGNED(time_t))
+ (void) sprintf(buf, "%ld",
+ (long) mkt);
+ else (void) sprintf(buf, "%lu",
+ (unsigned long) mkt);
+ pt = _add(buf, pt, ptlim);
+ }
continue;
case 'T':
pt = _fmt("%H:%M:%S", t, pt, ptlim);
@@ -300,67 +313,86 @@ label:
pt = _conv((t->tm_wday == 0) ? 7 : t->tm_wday,
"%d", pt, ptlim);
continue;
- case 'V':
- /*
- ** 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). The method for
- ** determining the week number is as specified
- ** by ISO 8601 (to wit: 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)."
- ** (ado, 5/24/93)
- */
- /*
- ** XXX--If January 1 falls on a Friday,
- ** January 1-3 are part of week 53 of the
- ** previous year. By analogy, if January
- ** 1 falls on a Thursday, are December 29-31
- ** of the PREVIOUS year part of week 1???
- ** (ado 5/24/93)
- */
- /*
- ** You are understood not to expect this.
- */
+ case 'V': /* ISO 8601 week number */
+ 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
+** year (the first Monday as the first day of week 1) as a decimal number
+** (01-53)."
+** (ado, 1993-05-24)
+**
+** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
+** "Week 01 of a year is per definition the first week which has the
+** Thursday in this year, which is equivalent to the week which contains
+** the fourth day of January. In other words, the first week of a new year
+** is the week which has the majority of its days in the new year. Week 01
+** 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
+** 1997 lasts from 1996-12-30 to 1997-01-05..."
+** (ado, 1996-01-02)
+*/
{
- int i;
-
- i = (t->tm_yday + 10 - (t->tm_wday ?
- (t->tm_wday - 1) : 6)) / 7;
- if (i == 0) {
+ int year;
+ int yday;
+ int wday;
+ int w;
+
+ year = t->tm_year + TM_YEAR_BASE;
+ yday = t->tm_yday;
+ wday = t->tm_wday;
+ for ( ; ; ) {
+ int len;
+ int bot;
+ int top;
+
+ len = isleap(year) ?
+ DAYSPERLYEAR :
+ DAYSPERNYEAR;
/*
- ** What day of the week does
- ** January 1 fall on?
+ ** What yday (-3 ... 3) does
+ ** the ISO year begin on?
*/
- i = t->tm_wday -
- (t->tm_yday - 1);
+ bot = ((yday + 11 - wday) %
+ DAYSPERWEEK) - 3;
/*
- ** Fri Jan 1: 53
- ** Sun Jan 1: 52
- ** Sat Jan 1: 53 if previous
- ** year a leap
- ** year, else 52
+ ** What yday does the NEXT
+ ** ISO year begin on?
*/
- if (i == TM_FRIDAY)
- i = 53;
- else if (i == TM_SUNDAY)
- i = 52;
- else i = isleap(t->tm_year +
- TM_YEAR_BASE) ?
- 53 : 52;
+ top = bot -
+ (len % DAYSPERWEEK);
+ if (top < -3)
+ top += DAYSPERWEEK;
+ top += len;
+ if (yday >= top) {
+ ++year;
+ w = 1;
+ break;
+ }
+ if (yday >= bot) {
+ w = 1 + ((yday - bot) /
+ DAYSPERWEEK);
+ break;
+ }
+ --year;
+ yday += isleap(year) ?
+ DAYSPERLYEAR :
+ DAYSPERNYEAR;
+ }
#ifdef XPG4_1994_04_09
- /*
- ** As of 4/9/94, though,
- ** XPG4 calls for 53
- ** unconditionally.
- */
- i = 53;
+ if (w == 52 && t->tm_mon == TM_JANUARY)
+ w = 53;
#endif /* defined XPG4_1994_04_09 */
- }
- pt = _conv(i, "%02d", pt, ptlim);
+ if (*format == 'V')
+ pt = _conv(w, "%02d",
+ pt, ptlim);
+ else if (*format == 'G')
+ pt = _conv(year, "%02d",
+ pt, ptlim);
+ else pt = _conv(year, "%04d",
+ pt, ptlim);
}
continue;
case 'v':
@@ -425,10 +457,10 @@ label:
static char *
_conv(n, format, pt, ptlim)
- const int n;
- const char *const format;
- char *const pt;
- const char *const ptlim;
+const int n;
+const char * const format;
+char * const pt;
+const char * const ptlim;
{
char buf[INT_STRLEN_MAXIMUM(int) + 1];
@@ -455,9 +487,9 @@ _secs(t, pt, ptlim)
static char *
_add(str, pt, ptlim)
- const char *str;
- char *pt;
- const char *const ptlim;
+const char * str;
+char * pt;
+const char * const ptlim;
{
while (pt < ptlim && (*pt = *str++) != '\0')
++pt;
diff --git a/lib/libc/stdtime/tzfile.h b/lib/libc/stdtime/tzfile.h
index 8d996dd..58cdc3d 100644
--- a/lib/libc/stdtime/tzfile.h
+++ b/lib/libc/stdtime/tzfile.h
@@ -1,10 +1,13 @@
-
-
#ifndef TZFILE_H
#define TZFILE_H
/*
+** This file is in the public domain, so clarified as of
+** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov).
+*/
+
+/*
** This header is for use ONLY with the time conversion code.
** There is no guarantee that it will remain unchanged,
** or that it will remain at all.
@@ -18,7 +21,9 @@
#ifndef lint
#ifndef NOID
-/*static char tzfilehid[] = "@(#)tzfile.h 7.6";*/
+/*
+static char tzfilehid[] = "@(#)tzfile.h 7.8";
+*/
#endif /* !defined NOID */
#endif /* !defined lint */
@@ -155,7 +160,7 @@ struct tzhead {
** that will probably do.
*/
-#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
#ifndef USG
OpenPOWER on IntegriCloud