From 1105a33fe3f75ced4b9a49822b7f2c9ba917c12f Mon Sep 17 00:00:00 2001 From: eck Date: Fri, 12 Oct 1990 14:48:55 +0000 Subject: [PATCH] added table for time-zone determination --- lang/cem/libcc.ansi/time/misc.c | 116 ++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 7 deletions(-) diff --git a/lang/cem/libcc.ansi/time/misc.c b/lang/cem/libcc.ansi/time/misc.c index 6f7ab192c..542323ea8 100644 --- a/lang/cem/libcc.ansi/time/misc.c +++ b/lang/cem/libcc.ansi/time/misc.c @@ -44,7 +44,7 @@ void _ftime(struct timeb *bp); * right value from the system. TZ is the only help. */ static char ntstr[TZ_LEN + 1] = "GMT"; /* string for normal time */ -static char dststr[TZ_LEN + 1] = "GMT"; /* string for daylight saving */ +static char dststr[TZ_LEN + 1] = "GDT"; /* string for daylight saving */ long _timezone = 0; long _dst_off = 60 * 60; @@ -84,6 +84,96 @@ const int _ytab[2][12] = { { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; +#if !defined(_POSIX_SOURCE) && !defined(__USG) +#define USE_TABLE 1 +#endif + +#if USE_TABLE +static int usetable = 1; + +typedef struct table { + const char *tz_name; + const int daylight; + const long zoneoffset; +} TABLE; + +#define HOUR(x) ((x) * 60*60) + +static TABLE TimezoneTable[] = { + {"GMT", 0, HOUR(0) }, /* Greenwich Mean */ + {"BST", 60*60, HOUR(0) }, /* British Summer */ + {"WAT", 0, HOUR(1) }, /* West Africa */ + {"AT", 0, HOUR(2) }, /* Azores */ + {"BST", 0, HOUR(3) }, /* Brazil Standard */ + {"NFT", 0, HOUR(3.5) }, /* Newfoundland */ + {"NDT", 60*60, HOUR(3.5) }, /* Newfoundland Daylight */ + {"AST", 0, HOUR(4) }, /* Atlantic Standard */ + {"ADT", 60*60, HOUR(4) }, /* Atlantic Daylight */ + {"EST", 0, HOUR(5) }, /* Eastern Standard */ + {"EDT", 60*60, HOUR(5) }, /* Eastern Daylight */ + {"CST", 0, HOUR(6) }, /* Central Standard */ + {"CDT", 60*60, HOUR(6) }, /* Central Daylight */ + {"MST", 0, HOUR(7) }, /* Mountain Standard */ + {"MDT", 60*60, HOUR(7) }, /* Mountain Daylight */ + {"PST", 0, HOUR(8) }, /* Pacific Standard */ + {"PDT", 60*60, HOUR(8) }, /* Pacific Daylight */ + {"YST", 0, HOUR(9) }, /* Yukon Standard */ + {"YDT", 60*60, HOUR(9) }, /* Yukon Daylight */ + {"HST", 0, HOUR(10) }, /* Hawaii Standard */ + {"HDT", 60*60, HOUR(10) }, /* Hawaii Daylight */ + {"NT", 0, HOUR(11) }, /* Nome */ + {"IDLW", 0, HOUR(12) }, /* International Date Line West */ + {"MET", 0, -HOUR(1) }, /* Middle European */ + {"MDT", 60*60, -HOUR(1) }, /* Middle European Summer */ + {"EET", 0, -HOUR(2) }, /* Eastern Europe, USSR Zone 1 */ + {"BT", 0, -HOUR(3) }, /* Baghdad, USSR Zone 2 */ + {"IT", 0, -HOUR(3.5) }, /* Iran */ + {"ZP4", 0, -HOUR(4) }, /* USSR Zone 3 */ + {"ZP5", 0, -HOUR(5) }, /* USSR Zone 4 */ + {"IST", 0, -HOUR(5.5) }, /* Indian Standard */ + {"ZP6", 0, -HOUR(6) }, /* USSR Zone 5 */ + {"NST", 0, -HOUR(6.5) }, /* North Sumatra */ + {"SST", 0, -HOUR(7) }, /* South Sumatra, USSR Zone 6 */ + {"WAST", 0, -HOUR(7) }, /* West Australian Standard */ + {"WADT", 60*60, -HOUR(7) }, /* West Australian Daylight */ + {"JT", 0, -HOUR(7.5) }, /* Java (3pm in Cronusland!) */ + {"CCT", 0, -HOUR(8) }, /* China Coast, USSR Zone 7 */ + {"JST", 0, -HOUR(9) }, /* Japan Standard, USSR Zone 8 */ + {"CAST", 0, -HOUR(9.5) }, /* Central Australian Standard */ + {"CADT", 60*60, -HOUR(9.5) }, /* Central Australian Daylight */ + {"EAST", 0, -HOUR(10) }, /* Eastern Australian Standard */ + {"EADT", 60*60, -HOUR(10) }, /* Eastern Australian Daylight */ + {"NZT", 0, -HOUR(12) }, /* New Zealand */ + {"NZDT", 60*60, -HOUR(12) }, /* New Zealand Daylight */ + { NULL, 0, 0 } +}; + +/* + * The function ZoneFromTable() searches the table for the current + * timezone. It saves the last one found in ntstr or dststr, depending on + * wheter the name is for daylight-saving-time or not. + * Both ntstr and dststr are TZ_LEN + 1 chars. + */ +static void +ZoneFromTable(long timezone) +{ + register TABLE *tptr = TimezoneTable; + + while (tptr->tz_name != NULL) { + if (tptr->zoneoffset == timezone) { + if (tptr->daylight == 0) { + strncpy(ntstr,tptr->tz_name, TZ_LEN); + ntstr[TZ_LEN] = '\0'; + } else { + strncpy(dststr,tptr->tz_name, TZ_LEN); + dststr[TZ_LEN] = '\0'; + } + } + tptr++; + } +} +#endif /* USE_TABLE */ + static const char * parseZoneName(register char *buf, register const char *p) { @@ -233,6 +323,9 @@ parseTZ(const char *p) if (!p) return; +#if USE_TABLE + usetable = 0; +#endif if (*p == ':') { /* * According to POSIX, this is implementation defined. @@ -294,7 +387,7 @@ _tzset(void) _gettimeofday(&tv, &tz); _daylight = tz.tz_dsttime; - _timezone = tz.tz_minuteswest * 60; + _timezone = tz.tz_minuteswest * 60L; #elif !defined(_POSIX_SOURCE) && !defined(__USG) @@ -357,11 +450,16 @@ date_of(register struct dsttype *dst, struct tm *timep) return day; } +/* + * The default dst transitions are those for Western Europe (except Great + * Britain). + */ unsigned _dstget(register struct tm *timep) { int begindst, enddst; register struct dsttype *dsts = &dststart, *dste = &dstend; + int do_dst = 0; if (_daylight == -1) _tzset(); @@ -379,13 +477,14 @@ _dstget(register struct tm *timep) /* assume begindst != enddst (otherwise it would be no use) */ if (begindst < enddst) { /* northern hemisphere */ if (timep->tm_yday > begindst && timep->tm_yday < enddst) - return _dst_off; + do_dst = 1; } else { /* southern hemisphere */ if (timep->tm_yday > begindst || timep->tm_yday < enddst) - return _dst_off; + do_dst = 1; } - if (timep->tm_yday == begindst || timep->tm_yday == enddst) { + if (!do_dst + && (timep->tm_yday == begindst || timep->tm_yday == enddst)) { long dsttranssec; /* transition when day is this old */ long cursec; @@ -397,9 +496,12 @@ _dstget(register struct tm *timep) if ((timep->tm_yday == begindst && cursec >= dsttranssec) || (timep->tm_yday == enddst && cursec < dsttranssec)) - return _dst_off; + do_dst = 1; } +#if USE_TABLE + if (usetable) ZoneFromTable(_timezone); +#endif + if (do_dst) return _dst_off; timep->tm_isdst = 0; - return 0; } -- 2.34.1