added table for time-zone determination
This commit is contained in:
parent
3672f835fe
commit
1105a33fe3
1 changed files with 109 additions and 7 deletions
|
@ -44,7 +44,7 @@ void _ftime(struct timeb *bp);
|
||||||
* right value from the system. TZ is the only help.
|
* right value from the system. TZ is the only help.
|
||||||
*/
|
*/
|
||||||
static char ntstr[TZ_LEN + 1] = "GMT"; /* string for normal time */
|
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 _timezone = 0;
|
||||||
long _dst_off = 60 * 60;
|
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 }
|
{ 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 *
|
static const char *
|
||||||
parseZoneName(register char *buf, register const char *p)
|
parseZoneName(register char *buf, register const char *p)
|
||||||
{
|
{
|
||||||
|
@ -233,6 +323,9 @@ parseTZ(const char *p)
|
||||||
|
|
||||||
if (!p) return;
|
if (!p) return;
|
||||||
|
|
||||||
|
#if USE_TABLE
|
||||||
|
usetable = 0;
|
||||||
|
#endif
|
||||||
if (*p == ':') {
|
if (*p == ':') {
|
||||||
/*
|
/*
|
||||||
* According to POSIX, this is implementation defined.
|
* According to POSIX, this is implementation defined.
|
||||||
|
@ -294,7 +387,7 @@ _tzset(void)
|
||||||
|
|
||||||
_gettimeofday(&tv, &tz);
|
_gettimeofday(&tv, &tz);
|
||||||
_daylight = tz.tz_dsttime;
|
_daylight = tz.tz_dsttime;
|
||||||
_timezone = tz.tz_minuteswest * 60;
|
_timezone = tz.tz_minuteswest * 60L;
|
||||||
|
|
||||||
#elif !defined(_POSIX_SOURCE) && !defined(__USG)
|
#elif !defined(_POSIX_SOURCE) && !defined(__USG)
|
||||||
|
|
||||||
|
@ -357,11 +450,16 @@ date_of(register struct dsttype *dst, struct tm *timep)
|
||||||
return day;
|
return day;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The default dst transitions are those for Western Europe (except Great
|
||||||
|
* Britain).
|
||||||
|
*/
|
||||||
unsigned
|
unsigned
|
||||||
_dstget(register struct tm *timep)
|
_dstget(register struct tm *timep)
|
||||||
{
|
{
|
||||||
int begindst, enddst;
|
int begindst, enddst;
|
||||||
register struct dsttype *dsts = &dststart, *dste = &dstend;
|
register struct dsttype *dsts = &dststart, *dste = &dstend;
|
||||||
|
int do_dst = 0;
|
||||||
|
|
||||||
if (_daylight == -1)
|
if (_daylight == -1)
|
||||||
_tzset();
|
_tzset();
|
||||||
|
@ -379,13 +477,14 @@ _dstget(register struct tm *timep)
|
||||||
/* assume begindst != enddst (otherwise it would be no use) */
|
/* assume begindst != enddst (otherwise it would be no use) */
|
||||||
if (begindst < enddst) { /* northern hemisphere */
|
if (begindst < enddst) { /* northern hemisphere */
|
||||||
if (timep->tm_yday > begindst && timep->tm_yday < enddst)
|
if (timep->tm_yday > begindst && timep->tm_yday < enddst)
|
||||||
return _dst_off;
|
do_dst = 1;
|
||||||
} else { /* southern hemisphere */
|
} else { /* southern hemisphere */
|
||||||
if (timep->tm_yday > begindst || timep->tm_yday < enddst)
|
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 dsttranssec; /* transition when day is this old */
|
||||||
long cursec;
|
long cursec;
|
||||||
|
|
||||||
|
@ -397,9 +496,12 @@ _dstget(register struct tm *timep)
|
||||||
|
|
||||||
if ((timep->tm_yday == begindst && cursec >= dsttranssec)
|
if ((timep->tm_yday == begindst && cursec >= dsttranssec)
|
||||||
|| (timep->tm_yday == enddst && 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;
|
timep->tm_isdst = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue