From fd15708e6476164990e7b364dc5b2aa1600f8e89 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Sat, 11 May 2002 05:40:55 +0000 Subject: Begin the process of reworking the time functions for proper time zone and locale support (in theory). More work is still needed. -Erik --- libc/misc/time/tm_conv.c | 113 ++++++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 71 deletions(-) (limited to 'libc/misc/time/tm_conv.c') diff --git a/libc/misc/time/tm_conv.c b/libc/misc/time/tm_conv.c index af82115e2..f73c96f07 100644 --- a/libc/misc/time/tm_conv.c +++ b/libc/misc/time/tm_conv.c @@ -1,79 +1,50 @@ -#if 0 -#include - -/* This is a translation from ALGOL in Collected Algorithms of CACM. */ -/* Copied from Algorithm 199, Author: Robert G. Tantzen */ - -void __tm_conv(tmbuf, timep, offset) -struct tm *tmbuf; -time_t *timep; -time_t offset; -{ - static int moffset[] = - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; +/* This is adapted from glibc */ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc */ - long s; - long j, d, m, y; +#define SECS_PER_HOUR 3600L +#define SECS_PER_DAY 86400L - offset += *timep; +#include +#include +#include - tmbuf->tm_isdst = 0; /* Someone else can set this */ +/* This structure contains all the information about a + timezone given in the POSIX standard TZ envariable. */ +typedef struct +{ + const char *name; - j = offset / 86400L + 719469; - s = offset % 86400L; + /* When to change. */ + enum { J0, J1, M } type; /* Interpretation of: */ + unsigned short int m, n, d; /* Month, week, day. */ + unsigned int secs; /* Time of day. */ - if (s < 0) { - s += 86400L; - j--; - } + long int offset; /* Seconds east of GMT (west if < 0). */ - tmbuf->tm_sec = s % 60; - tmbuf->tm_min = (s / 60) % 60; - tmbuf->tm_hour = s / 3600; - - tmbuf->tm_wday = (j + 2) % 7; - - /* - * Julian date converter. Takes a julian date (the number of days since - * some distant epoch or other), and fills tmbuf. - */ - - y = (4L * j - 1L) / 146097L; - j = 4L * j - 1L - 146097L * y; - d = j / 4L; - j = (4L * d + 3L) / 1461L; - d = 4L * d + 3L - 1461L * j; - d = (d + 4L) / 4L; - m = (5L * d - 3L) / 153L; - d = 5L * d - 3 - 153L * m; - d = (d + 5L) / 5L; - y = 100L * y + j; - if (m < 10) - m += 2; - else { - m -= 10; - ++y; - } + /* We cache the computed time of change for a + given year so we don't have to recompute it. */ + time_t change; /* When to change to this zone. */ + int computed_for; /* Year above is computed for. */ +} tz_rule; - tmbuf->tm_year = y - 1900; - tmbuf->tm_mon = m; - tmbuf->tm_mday = d; +/* tz_rules[0] is standard, tz_rules[1] is daylight. */ +static tz_rule tz_rules[2]; - tmbuf->tm_yday = d + moffset[m]; - if (m > 1 && ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0))) - tmbuf->tm_yday++; +/* Warning -- this function is a stub andd always does UTC + * no matter what it is given */ +void tzset (void) +{ + tz_rules[0].name = tz_rules[1].name = "UTC"; + tz_rules[0].type = tz_rules[1].type = J0; + tz_rules[0].m = tz_rules[0].n = tz_rules[0].d = 0; + tz_rules[1].m = tz_rules[1].n = tz_rules[1].d = 0; + tz_rules[0].secs = tz_rules[1].secs = 0; + tz_rules[0].offset = tz_rules[1].offset = 0L; + tz_rules[0].change = tz_rules[1].change = (time_t) -1; + tz_rules[0].computed_for = tz_rules[1].computed_for = 0; } -#else - -/* This is adapted from glibc */ -/* Copyright (C) 1991, 1993 Free Software Foundation, Inc */ - -#define SECS_PER_HOUR 3600L -#define SECS_PER_DAY 86400L - -#include static const unsigned short int __mon_lengths[2][12] = { /* Normal years. */ @@ -82,11 +53,9 @@ static const unsigned short int __mon_lengths[2][12] = { {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; -void __tm_conv(tmbuf, t, offset) -struct tm *tmbuf; -time_t *t; -time_t offset; +void __tm_conv(struct tm *tmbuf, time_t *t, time_t offset) { + int isdst; long days, rem; register int y; register const unsigned short int *ip; @@ -128,7 +97,9 @@ time_t offset; days -= ip[y]; tmbuf->tm_mon = y; tmbuf->tm_mday = days + 1; - tmbuf->tm_isdst = -1; + isdst = (*t >= tz_rules[0].change && *t < tz_rules[1].change); + tmbuf->tm_isdst = isdst; + tmbuf->tm_zone = tzname[isdst]; + } -#endif -- cgit v1.2.3