Re: Proposal for better support of time-varying timezone abbreviations - Mailing list pgsql-hackers (2024)

From Tom Lane
Subject Re: Proposal for better support of time-varying timezone abbreviations
Date October 8,2014
Msg-id 28124.1412719520@sss.pgh.pa.us
Whole thread Raw
Inresponseto Proposal for better support of time-varying timezone abbreviations (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Proposal for better support of time-varying timezone abbreviations
List pgsql-hackers
I wrote:> 4. I've eyeballed the relevant code a bit, and it seems that the only> implementation aspect that isn't perfectly straightforward is figuring> out how to cram a zic timezone reference into a datetkn table entry.> I suggest that before tackling this feature proper, we bring struct> datetkn into the 21st century by widening it from 12 to 16 bytes, along> the lines of> typedef struct> {> char token[TOKMAXLEN + 1]; /* now always null-terminated */> char type;> int32 value;> } datetkn;> and getting rid of all of the very crufty code that deals with> non-null-terminated token strings and cramming values that don't really> fit into a char-sized field into "value". (We might save more code bytes> that way than we spend on the wider token-table entries :-( ... and we'll> certainly make the code less ugly.)Attached is a proposed patch for this part. It turned out to be quitea bit more exciting (not in a good way) than I'd expected. Somewherealong the way, somebody decided that the easiest way to get from point Ato point B was to insert a minus sign into the FROMVAL() macro, meaningthat FROMVAL() and TOVAL() were not inverses as one would rationallyexpect. There were various ways that one could deal with this bit ofdirty laundry; in particular I considered flipping the sign definitionof TZ/DTZ entry values. It seemed better in the end to keep the signthe same (matching the IANA code's convention for timezone offset sign)and negate the results at the call sites where needed. Since, in anotherbit of weird design, all those call sites already had a multiplicationby MINS_PER_HOUR (the wrong spelling of "60", btw, but I digress) thatneeded to be got rid of, this didn't result in touching more placesthan I would have had to anyway.Much worse for the present effort: I was reminded that ecpg containsa *hard wired* list of known zone abbreviations and their GMT offsets;a list that doesn't seem to have been updated since around 2003. I'mnot sure what a reasonable fix would be for that. ecpg can't assume ithas access to the timezone database, probably, so bringing it up tospeed with what I propose to do in the backend doesn't seem feasible.For the moment I didn't change the data there, even though a lot ofthe entries are obsolete.The attached patch also fixes a possible free()-of-uninitialized-pointerproblem in PGTYPEStimestamp_defmt_scan(). regards, tom lanediff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.cindex 073104d..195ac6e 100644*** a/src/backend/utils/adt/date.c--- b/src/backend/utils/adt/date.c*************** timetz_zone(PG_FUNCTION_ARGS)*** 2710,2718 **** type = DecodeSpecial(0, lowzone, &val); if (type == TZ || type == DTZ)! tz = val * MINS_PER_HOUR; else { tzp = pg_tzset(tzname); if (tzp) {--- 2710,2722 ---- type = DecodeSpecial(0, lowzone, &val); if (type == TZ || type == DTZ)! {! /* abbreviation */! tz = -val;! } else {+ /* try it as a full zone name */ tzp = pg_tzset(tzname); if (tzp) {diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.cindex 7632d11..b159a08 100644*** a/src/backend/utils/adt/datetime.c--- b/src/backend/utils/adt/datetime.c*************** const char *const days[] = {"Sunday", "M*** 70,101 **** *****************************************************************************/ /*- * Definitions for squeezing values into "value"- * We set aside a high bit for a sign, and scale the timezone offsets- * in minutes by a factor of 15 (so can represent quarter-hour increments).- */- #define ABS_SIGNBIT ((char) 0200)- #define VALMASK ((char) 0177)- #define POS(n) (n)- #define NEG(n) ((n)|ABS_SIGNBIT)- #define SIGNEDCHAR(c) ((c)&ABS_SIGNBIT? -((c)&VALMASK): (c))- #define FROMVAL(tp) (-SIGNEDCHAR((tp)->value) * 15) /* uncompress */- #define TOVAL(tp, v) ((tp)->value = ((v) < 0? NEG((-(v))/15): POS(v)/15))-- /* * datetktbl holds date/time keywords. * * Note that this table must be strictly alphabetically ordered to allow an * O(ln(N)) search algorithm to be used. *! * The token field is NOT guaranteed to be NULL-terminated.! *! * To keep this table reasonably small, we divide the value for TZ and DTZ! * entries by 15 (so they are on 15 minute boundaries) and truncate the token! * field at TOKMAXLEN characters.! * Formerly, we divided by 10 rather than 15 but there are a few time zones! * which are 30 or 45 minutes away from an even hour, most are on an hour! * boundary, and none on other boundaries. * * The static table contains no TZ or DTZ entries, rather those are loaded * from configuration files and stored in timezonetktbl, which has the same--- 70,82 ---- *****************************************************************************/ /* * datetktbl holds date/time keywords. * * Note that this table must be strictly alphabetically ordered to allow an * O(ln(N)) search algorithm to be used. *! * The token field must be NUL-terminated; we truncate entries to TOKMAXLEN! * characters to fit. * * The static table contains no TZ or DTZ entries, rather those are loaded * from configuration files and stored in timezonetktbl, which has the same*************** static const datetkn datetktbl[] = {*** 123,129 **** {"december", MONTH, 12}, {"dow", RESERV, DTK_DOW}, /* day of week */ {"doy", RESERV, DTK_DOY}, /* day of year */! {"dst", DTZMOD, 6}, {EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */ {"feb", MONTH, 2}, {"february", MONTH, 2},--- 104,110 ---- {"december", MONTH, 12}, {"dow", RESERV, DTK_DOW}, /* day of week */ {"doy", RESERV, DTK_DOY}, /* day of year */! {"dst", DTZMOD, SECS_PER_HOUR}, {EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */ {"feb", MONTH, 2}, {"february", MONTH, 2},*************** static const datetkn datetktbl[] = {*** 185,190 ****--- 166,175 ---- static int szdatetktbl = sizeof datetktbl / sizeof datetktbl[0];+ /*+ * deltatktbl: same format as datetktbl, but holds keywords used to represent+ * time units (eg, for intervals, and for EXTRACT).+ */ static const datetkn deltatktbl[] = { /* token, type, value */ {"@", IGNORE_DTF, 0}, /* postgres relative prefix */*************** DecodeDateTime(char **field, int *ftype,*** 1286,1292 **** tm->tm_isdst = 1; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp += val * MINS_PER_HOUR; break; case DTZ:--- 1271,1277 ---- tm->tm_isdst = 1; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp -= val; break; case DTZ:*************** DecodeDateTime(char **field, int *ftype,*** 1299,1312 **** tm->tm_isdst = 1; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp = val * MINS_PER_HOUR; break; case TZ: tm->tm_isdst = 0; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp = val * MINS_PER_HOUR; break; case IGNORE_DTF:--- 1284,1297 ---- tm->tm_isdst = 1; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp = -val; break; case TZ: tm->tm_isdst = 0; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp = -val; break; case IGNORE_DTF:*************** DecodeTimeOnly(char **field, int *ftype,*** 1978,1984 **** tm->tm_isdst = 1; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp += val * MINS_PER_HOUR; break; case DTZ:--- 1963,1969 ---- tm->tm_isdst = 1; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp -= val; break; case DTZ:*************** DecodeTimeOnly(char **field, int *ftype,*** 1991,1997 **** tm->tm_isdst = 1; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp = val * MINS_PER_HOUR; ftype[i] = DTK_TZ; break;--- 1976,1982 ---- tm->tm_isdst = 1; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp = -val; ftype[i] = DTK_TZ; break;*************** DecodeTimeOnly(char **field, int *ftype,*** 1999,2005 **** tm->tm_isdst = 0; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp = val * MINS_PER_HOUR; ftype[i] = DTK_TZ; break;--- 1984,1990 ---- tm->tm_isdst = 0; if (tzp == NULL) return DTERR_BAD_FORMAT;! *tzp = -val; ftype[i] = DTK_TZ; break;*************** DecodeSpecial(int field, char *lowtoken,*** 2792,2797 ****--- 2777,2783 ---- const datetkn *tp; tp = datecache[field];+ /* use strncmp so that we match truncated tokens */ if (tp == NULL || strncmp(lowtoken, tp->token, TOKMAXLEN) != 0) { tp = datebsearch(lowtoken, timezonetktbl, sztimezonetktbl);*************** DecodeSpecial(int field, char *lowtoken,*** 2807,2824 **** { datecache[field] = tp; type = tp->type;! switch (type)! {! case TZ:! case DTZ:! case DTZMOD:! *val = FROMVAL(tp);! break;!! default:! *val = tp->value;! break;! } } return type;--- 2793,2799 ---- { datecache[field] = tp; type = tp->type;! *val = tp->value; } return type;*************** DecodeUnits(int field, char *lowtoken, i*** 3504,3509 ****--- 3479,3485 ---- const datetkn *tp; tp = deltacache[field];+ /* use strncmp so that we match truncated tokens */ if (tp == NULL || strncmp(lowtoken, tp->token, TOKMAXLEN) != 0) { tp = datebsearch(lowtoken, deltatktbl, szdeltatktbl);*************** DecodeUnits(int field, char *lowtoken, i*** 3517,3526 **** { deltacache[field] = tp; type = tp->type;! if (type == TZ || type == DTZ)! *val = FROMVAL(tp);! else! *val = tp->value; } return type;--- 3493,3499 ---- { deltacache[field] = tp; type = tp->type;! *val = tp->value; } return type;*************** datebsearch(const char *key, const datet*** 3593,3601 **** while (last >= base) { position = base + ((last - base) >> 1);! result = key[0] - position->token[0]; if (result == 0) { result = strncmp(key, position->token, TOKMAXLEN); if (result == 0) return position;--- 3566,3576 ---- while (last >= base) { position = base + ((last - base) >> 1);! /* precheck the first character for a bit of extra speed */! result = (int) key[0] - (int) position->token[0]; if (result == 0) {+ /* use strncmp so that we match truncated tokens */ result = strncmp(key, position->token, TOKMAXLEN); if (result == 0) return position;*************** CheckDateTokenTable(const char *tablenam*** 4142,4156 **** bool ok = true; int i;! for (i = 1; i < nel; i++) {! if (strncmp(base[i - 1].token, base[i].token, TOKMAXLEN) >= 0) { /* %.*s is safe since all our tokens are ASCII */! elog(LOG, "ordering error in %s table: \"%.*s\" >= \"%.*s\"", tablename,! TOKMAXLEN, base[i - 1].token,! TOKMAXLEN, base[i].token); ok = false; } }--- 4117,4142 ---- bool ok = true; int i;! for (i = 0; i < nel; i++) {! /* check for token strings that don't fit */! if (strlen(base[i].token) > TOKMAXLEN) { /* %.*s is safe since all our tokens are ASCII */! elog(LOG, "token too long in %s table: \"%.*s\"", tablename,! TOKMAXLEN + 1, base[i].token);! ok = false;! break; /* don't risk applying strcmp */! }! /* check for out of order */! if (i > 0 &&! strcmp(base[i - 1].token, base[i].token) >= 0)! {! elog(LOG, "ordering error in %s table: \"%s\" >= \"%s\"",! tablename,! base[i - 1].token,! base[i].token); ok = false; } }*************** ConvertTimeZoneAbbrevs(TimeZoneAbbrevTab*** 4221,4230 **** tbl->numabbrevs = n; for (i = 0; i < n; i++) {! /* do NOT use strlcpy here; token field need not be null-terminated */! strncpy(newtbl[i].token, abbrevs[i].abbrev, TOKMAXLEN); newtbl[i].type = abbrevs[i].is_dst ? DTZ : TZ;! TOVAL(&newtbl[i], abbrevs[i].offset / MINS_PER_HOUR); } /* Check the ordering, if testing */--- 4207,4216 ---- tbl->numabbrevs = n; for (i = 0; i < n; i++) {! /* use strlcpy to truncate name if necessary */! strlcpy(newtbl[i].token, abbrevs[i].abbrev, TOKMAXLEN + 1); newtbl[i].type = abbrevs[i].is_dst ? DTZ : TZ;! newtbl[i].value = abbrevs[i].offset; } /* Check the ordering, if testing */*************** pg_timezone_abbrevs(PG_FUNCTION_ARGS)*** 4315,4329 **** * Convert name to text, using upcasing conversion that is the inverse of * what ParseDateTime() uses. */! strncpy(buffer, timezonetktbl[*pindex].token, TOKMAXLEN);! buffer[TOKMAXLEN] = '\0'; /* may not be null-terminated */ for (p = (unsigned char *) buffer; *p; p++) *p = pg_toupper(*p); values[0] = CStringGetTextDatum(buffer); MemSet(&tm, 0, sizeof(struct pg_tm));! tm.tm_min = (-1) * FROMVAL(&timezonetktbl[*pindex]); resInterval = (Interval *) palloc(sizeof(Interval)); tm2interval(&tm, 0, resInterval); values[1] = IntervalPGetDatum(resInterval);--- 4301,4315 ---- * Convert name to text, using upcasing conversion that is the inverse of * what ParseDateTime() uses. */! strlcpy(buffer, timezonetktbl[*pindex].token, sizeof(buffer)); for (p = (unsigned char *) buffer; *p; p++) *p = pg_toupper(*p); values[0] = CStringGetTextDatum(buffer);+ /* Convert offset (in seconds) to an interval */ MemSet(&tm, 0, sizeof(struct pg_tm));! tm.tm_sec = timezonetktbl[*pindex].value; resInterval = (Interval *) palloc(sizeof(Interval)); tm2interval(&tm, 0, resInterval); values[1] = IntervalPGetDatum(resInterval);diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.cindex 11007c6..de1e1fc 100644*** a/src/backend/utils/adt/timestamp.c--- b/src/backend/utils/adt/timestamp.c*************** parse_sane_timezone(struct pg_tm * tm, t*** 540,548 **** type = DecodeSpecial(0, lowzone, &val); if (type == TZ || type == DTZ)! tz = val * MINS_PER_HOUR; else { pg_tz *tzp; tzp = pg_tzset(tzname);--- 540,552 ---- type = DecodeSpecial(0, lowzone, &val); if (type == TZ || type == DTZ)! {! /* abbreviation */! tz = -val;! } else {+ /* try it as a full zone name */ pg_tz *tzp; tzp = pg_tzset(tzname);*************** timestamp_zone(PG_FUNCTION_ARGS)*** 4904,4914 **** if (type == TZ || type == DTZ) {! tz = -(val * MINS_PER_HOUR); result = dt2local(timestamp, tz); } else { tzp = pg_tzset(tzname); if (tzp) {--- 4908,4920 ---- if (type == TZ || type == DTZ) {! /* abbreviation */! tz = val; result = dt2local(timestamp, tz); } else {+ /* try it as a full zone name */ tzp = pg_tzset(tzname); if (tzp) {*************** timestamptz_zone(PG_FUNCTION_ARGS)*** 5077,5087 **** if (type == TZ || type == DTZ) {! tz = val * MINS_PER_HOUR; result = dt2local(timestamp, tz); } else { tzp = pg_tzset(tzname); if (tzp) {--- 5083,5095 ---- if (type == TZ || type == DTZ) {! /* abbreviation */! tz = -val; result = dt2local(timestamp, tz); } else {+ /* try it as a full zone name */ tzp = pg_tzset(tzname); if (tzp) {diff --git a/src/backend/utils/misc/tzparser.c b/src/backend/utils/misc/tzparser.cindex 6a5a7b3..f947668 100644*** a/src/backend/utils/misc/tzparser.c--- b/src/backend/utils/misc/tzparser.c*************** validateTzEntry(tzEntry *tzentry)*** 63,75 **** tzentry->filename, tzentry->lineno); return false; }- if (tzentry->offset % 900 != 0)- {- GUC_check_errmsg("time zone offset %d is not a multiple of 900 sec (15 min) in time zone file \"%s\", line%d",- tzentry->offset,- tzentry->filename, tzentry->lineno);- return false;- } /* * Sanity-check the offset: shouldn't exceed 14 hours--- 63,68 ----diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.hindex 2e69503..2a26bf7 100644*** a/src/include/utils/datetime.h--- b/src/include/utils/datetime.h*************** struct tzEntry;*** 124,131 **** /* * Token field definitions for time parsing and decoding.! * These need to fit into the datetkn table type.! * At the moment, that means keep them within [-127,127]. * These are also used for bit masks in DecodeDateDelta() * so actually restrict them to within [0,31] for now. * - thomas 97/06/19--- 124,131 ---- /* * Token field definitions for time parsing and decoding.! * These need to fit into the datetkn struct's type field.! * At the moment, that means keep them within [0,127]. * These are also used for bit masks in DecodeDateDelta() * so actually restrict them to within [0,31] for now. * - thomas 97/06/19*************** struct tzEntry;*** 203,211 **** /* keep this struct small; it gets used a lot */ typedef struct {! char token[TOKMAXLEN]; char type;! char value; /* this may be unsigned, alas */ } datetkn; /* one of its uses is in tables of time zone abbreviations */--- 203,211 ---- /* keep this struct small; it gets used a lot */ typedef struct {! char token[TOKMAXLEN + 1]; /* now always null-terminated */ char type;! int32 value; } datetkn; /* one of its uses is in tables of time zone abbreviations */diff --git a/src/interfaces/ecpg/pgtypeslib/dt.h b/src/interfaces/ecpg/pgtypeslib/dt.hindex c2635c7..8ece8df 100644*** a/src/interfaces/ecpg/pgtypeslib/dt.h--- b/src/interfaces/ecpg/pgtypeslib/dt.h*************** typedef double fsec_t;*** 130,137 **** /* * Token field definitions for time parsing and decoding.! * These need to fit into the datetkn table type.! * At the moment, that means keep them within [-127,127]. * These are also used for bit masks in DecodeDateDelta() * so actually restrict them to within [0,31] for now. * - thomas 97/06/19--- 130,137 ---- /* * Token field definitions for time parsing and decoding.! * These need to fit into the datetkn struct's type field.! * At the moment, that means keep them within [0,127]. * These are also used for bit masks in DecodeDateDelta() * so actually restrict them to within [0,31] for now. * - thomas 97/06/19*************** typedef double fsec_t;*** 207,219 **** /* keep this struct small; it gets used a lot */ typedef struct {! #if defined(_AIX)! char *token;! #else! char token[TOKMAXLEN];! #endif /* _AIX */ char type;! char value; /* this may be unsigned, alas */ } datetkn;--- 207,215 ---- /* keep this struct small; it gets used a lot */ typedef struct {! char token[TOKMAXLEN + 1]; /* now always null-terminated */ char type;! int32 value; } datetkn;diff --git a/src/interfaces/ecpg/pgtypeslib/dt_common.c b/src/interfaces/ecpg/pgtypeslib/dt_common.cindex 2286acd..7fdd09b 100644*** a/src/interfaces/ecpg/pgtypeslib/dt_common.c--- b/src/interfaces/ecpg/pgtypeslib/dt_common.c*************** int day_tab[2][13] = {*** 16,53 **** typedef long AbsoluteTime;- #define ABS_SIGNBIT ((char) 0200)- #define POS(n) (n)- #define NEG(n) ((n)|ABS_SIGNBIT)- #define FROMVAL(tp) (-SIGNEDCHAR((tp)->value) * 15) /* uncompress */- #define VALMASK ((char) 0177)- #define SIGNEDCHAR(c) ((c)&ABS_SIGNBIT? -((c)&VALMASK): (c))- static datetkn datetktbl[] = { /* text, token, lexval */ {EARLY, RESERV, DTK_EARLY}, /* "-infinity" reserved for "early time" */! {"acsst", DTZ, POS(42)}, /* Cent. Australia */! {"acst", DTZ, NEG(16)}, /* Atlantic/Porto Acre */! {"act", TZ, NEG(20)}, /* Atlantic/Porto Acre */ {DA_D, ADBC, AD}, /* "ad" for years >= 0 */! {"adt", DTZ, NEG(12)}, /* Atlantic Daylight Time */! {"aesst", DTZ, POS(44)}, /* E. Australia */! {"aest", TZ, POS(40)}, /* Australia Eastern Std Time */! {"aft", TZ, POS(18)}, /* Kabul */! {"ahst", TZ, NEG(40)}, /* Alaska-Hawaii Std Time */! {"akdt", DTZ, NEG(32)}, /* Alaska Daylight Time */! {"akst", DTZ, NEG(36)}, /* Alaska Standard Time */ {"allballs", RESERV, DTK_ZULU}, /* 00:00:00 */! {"almst", TZ, POS(28)}, /* Almaty Savings Time */! {"almt", TZ, POS(24)}, /* Almaty Time */ {"am", AMPM, AM},! {"amst", DTZ, POS(20)}, /* Armenia Summer Time (Yerevan) */ #if 0! {"amst", DTZ, NEG(12)}, /* Porto Velho */ #endif! {"amt", TZ, POS(16)}, /* Armenia Time (Yerevan) */! {"anast", DTZ, POS(52)}, /* Anadyr Summer Time (Russia) */! {"anat", TZ, POS(48)}, /* Anadyr Time (Russia) */ {"apr", MONTH, 4}, {"april", MONTH, 4}, #if 0--- 16,46 ---- typedef long AbsoluteTime; static datetkn datetktbl[] = { /* text, token, lexval */ {EARLY, RESERV, DTK_EARLY}, /* "-infinity" reserved for "early time" */! {"acsst", DTZ, 37800}, /* Cent. Australia */! {"acst", DTZ, -14400}, /* Atlantic/Porto Acre */! {"act", TZ, -18000}, /* Atlantic/Porto Acre */ {DA_D, ADBC, AD}, /* "ad" for years >= 0 */! {"adt", DTZ, -10800}, /* Atlantic Daylight Time */! {"aesst", DTZ, 39600}, /* E. Australia */! {"aest", TZ, 36000}, /* Australia Eastern Std Time */! {"aft", TZ, 16200}, /* Kabul */! {"ahst", TZ, -36000}, /* Alaska-Hawaii Std Time */! {"akdt", DTZ, -28800}, /* Alaska Daylight Time */! {"akst", DTZ, -32400}, /* Alaska Standard Time */ {"allballs", RESERV, DTK_ZULU}, /* 00:00:00 */! {"almst", TZ, 25200}, /* Almaty Savings Time */! {"almt", TZ, 21600}, /* Almaty Time */ {"am", AMPM, AM},! {"amst", DTZ, 18000}, /* Armenia Summer Time (Yerevan) */ #if 0! {"amst", DTZ, -10800}, /* Porto Velho */ #endif! {"amt", TZ, 14400}, /* Armenia Time (Yerevan) */! {"anast", DTZ, 46800}, /* Anadyr Summer Time (Russia) */! {"anat", TZ, 43200}, /* Anadyr Time (Russia) */ {"apr", MONTH, 4}, {"april", MONTH, 4}, #if 0*************** static datetkn datetktbl[] = {*** 55,430 **** aqtt arst #endif! {"art", TZ, NEG(12)}, /* Argentina Time */ #if 0 ashst ast /* Atlantic Standard Time, Arabia Standard * Time, Acre Standard Time */ #endif! {"ast", TZ, NEG(16)}, /* Atlantic Std Time (Canada) */ {"at", IGNORE_DTF, 0}, /* "at" (throwaway) */ {"aug", MONTH, 8}, {"august", MONTH, 8},! {"awsst", DTZ, POS(36)}, /* W. Australia */! {"awst", TZ, POS(32)}, /* W. Australia */! {"awt", DTZ, NEG(12)},! {"azost", DTZ, POS(0)}, /* Azores Summer Time */! {"azot", TZ, NEG(4)}, /* Azores Time */! {"azst", DTZ, POS(20)}, /* Azerbaijan Summer Time */! {"azt", TZ, POS(16)}, /* Azerbaijan Time */ {DB_C, ADBC, BC}, /* "bc" for years < 0 */! {"bdst", TZ, POS(8)}, /* British Double Summer Time */! {"bdt", TZ, POS(24)}, /* Dacca */! {"bnt", TZ, POS(32)}, /* Brunei Darussalam Time */! {"bort", TZ, POS(32)}, /* Borneo Time (Indonesia) */ #if 0 bortst bost #endif! {"bot", TZ, NEG(16)}, /* Bolivia Time */! {"bra", TZ, NEG(12)}, /* Brazil Time */ #if 0 brst brt #endif! {"bst", DTZ, POS(4)}, /* British Summer Time */ #if 0! {"bst", TZ, NEG(12)}, /* Brazil Standard Time */! {"bst", DTZ, NEG(44)}, /* Bering Summer Time */ #endif! {"bt", TZ, POS(12)}, /* Baghdad Time */! {"btt", TZ, POS(24)}, /* Bhutan Time */! {"cadt", DTZ, POS(42)}, /* Central Australian DST */! {"cast", TZ, POS(38)}, /* Central Australian ST */! {"cat", TZ, NEG(40)}, /* Central Alaska Time */! {"cct", TZ, POS(32)}, /* China Coast Time */ #if 0! {"cct", TZ, POS(26)}, /* Indian Cocos (Island) Time */ #endif! {"cdt", DTZ, NEG(20)}, /* Central Daylight Time */! {"cest", DTZ, POS(8)}, /* Central European Dayl.Time */! {"cet", TZ, POS(4)}, /* Central European Time */! {"cetdst", DTZ, POS(8)}, /* Central European Dayl.Time */! {"chadt", DTZ, POS(55)}, /* Chatham Island Daylight Time (13:45) */! {"chast", TZ, POS(51)}, /* Chatham Island Time (12:45) */ #if 0 ckhst #endif! {"ckt", TZ, POS(48)}, /* Cook Islands Time */! {"clst", DTZ, NEG(12)}, /* Chile Summer Time */! {"clt", TZ, NEG(16)}, /* Chile Time */ #if 0 cost #endif! {"cot", TZ, NEG(20)}, /* Columbia Time */! {"cst", TZ, NEG(24)}, /* Central Standard Time */ {DCURRENT, RESERV, DTK_CURRENT}, /* "current" is always now */ #if 0 cvst #endif! {"cvt", TZ, POS(28)}, /* Christmas Island Time (Indian Ocean) */! {"cxt", TZ, POS(28)}, /* Christmas Island Time (Indian Ocean) */ {"d", UNITS, DTK_DAY}, /* "day of month" for ISO input */! {"davt", TZ, POS(28)}, /* Davis Time (Antarctica) */! {"ddut", TZ, POS(40)}, /* Dumont-d'Urville Time (Antarctica) */ {"dec", MONTH, 12}, {"december", MONTH, 12},! {"dnt", TZ, POS(4)}, /* Dansk Normal Tid */ {"dow", RESERV, DTK_DOW}, /* day of week */ {"doy", RESERV, DTK_DOY}, /* day of year */! {"dst", DTZMOD, 6}, #if 0! {"dusst", DTZ, POS(24)}, /* Dushanbe Summer Time */ #endif! {"easst", DTZ, NEG(20)}, /* Easter Island Summer Time */! {"east", TZ, NEG(24)}, /* Easter Island Time */! {"eat", TZ, POS(12)}, /* East Africa Time */ #if 0! {"east", DTZ, POS(16)}, /* Indian Antananarivo Savings Time */! {"eat", TZ, POS(12)}, /* Indian Antananarivo Time */! {"ect", TZ, NEG(16)}, /* Eastern Caribbean Time */! {"ect", TZ, NEG(20)}, /* Ecuador Time */ #endif! {"edt", DTZ, NEG(16)}, /* Eastern Daylight Time */! {"eest", DTZ, POS(12)}, /* Eastern Europe Summer Time */! {"eet", TZ, POS(8)}, /* East. Europe, USSR Zone 1 */! {"eetdst", DTZ, POS(12)}, /* Eastern Europe Daylight Time */! {"egst", DTZ, POS(0)}, /* East Greenland Summer Time */! {"egt", TZ, NEG(4)}, /* East Greenland Time */ #if 0 ehdt #endif {EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */! {"est", TZ, NEG(20)}, /* Eastern Standard Time */ {"feb", MONTH, 2}, {"february", MONTH, 2},! {"fjst", DTZ, NEG(52)}, /* Fiji Summer Time (13 hour offset!) */! {"fjt", TZ, NEG(48)}, /* Fiji Time */! {"fkst", DTZ, NEG(12)}, /* Falkland Islands Summer Time */! {"fkt", TZ, NEG(8)}, /* Falkland Islands Time */ #if 0 fnst fnt #endif {"fri", DOW, 5}, {"friday", DOW, 5},! {"fst", TZ, POS(4)}, /* French Summer Time */! {"fwt", DTZ, POS(8)}, /* French Winter Time */! {"galt", TZ, NEG(24)}, /* Galapagos Time */! {"gamt", TZ, NEG(36)}, /* Gambier Time */! {"gest", DTZ, POS(20)}, /* Georgia Summer Time */! {"get", TZ, POS(16)}, /* Georgia Time */! {"gft", TZ, NEG(12)}, /* French Guiana Time */ #if 0 ghst #endif! {"gilt", TZ, POS(48)}, /* Gilbert Islands Time */! {"gmt", TZ, POS(0)}, /* Greenwish Mean Time */! {"gst", TZ, POS(40)}, /* Guam Std Time, USSR Zone 9 */! {"gyt", TZ, NEG(16)}, /* Guyana Time */ {"h", UNITS, DTK_HOUR}, /* "hour" */ #if 0 hadt hast #endif! {"hdt", DTZ, NEG(36)}, /* Hawaii/Alaska Daylight Time */ #if 0 hkst #endif! {"hkt", TZ, POS(32)}, /* Hong Kong Time */ #if 0! {"hmt", TZ, POS(12)}, /* Hellas ? ? */ hovst hovt #endif! {"hst", TZ, NEG(40)}, /* Hawaii Std Time */ #if 0 hwt #endif! {"ict", TZ, POS(28)}, /* Indochina Time */! {"idle", TZ, POS(48)}, /* Intl. Date Line, East */! {"idlw", TZ, NEG(48)}, /* Intl. Date Line, West */ #if 0 idt /* Israeli, Iran, Indian Daylight Time */ #endif {LATE, RESERV, DTK_LATE}, /* "infinity" reserved for "late time" */ {INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for bad time */! {"iot", TZ, POS(20)}, /* Indian Chagos Time */! {"irkst", DTZ, POS(36)}, /* Irkutsk Summer Time */! {"irkt", TZ, POS(32)}, /* Irkutsk Time */! {"irt", TZ, POS(14)}, /* Iran Time */ {"isodow", RESERV, DTK_ISODOW}, /* ISO day of week, Sunday == 7 */ #if 0 isst #endif! {"ist", TZ, POS(8)}, /* Israel */! {"it", TZ, POS(14)}, /* Iran Time */ {"j", UNITS, DTK_JULIAN}, {"jan", MONTH, 1}, {"january", MONTH, 1},! {"javt", TZ, POS(28)}, /* Java Time (07:00? see JT) */! {"jayt", TZ, POS(36)}, /* Jayapura Time (Indonesia) */ {"jd", UNITS, DTK_JULIAN},! {"jst", TZ, POS(36)}, /* Japan Std Time,USSR Zone 8 */! {"jt", TZ, POS(30)}, /* Java Time (07:30? see JAVT) */ {"jul", MONTH, 7}, {"julian", UNITS, DTK_JULIAN}, {"july", MONTH, 7}, {"jun", MONTH, 6}, {"june", MONTH, 6},! {"kdt", DTZ, POS(40)}, /* Korea Daylight Time */! {"kgst", DTZ, POS(24)}, /* Kyrgyzstan Summer Time */! {"kgt", TZ, POS(20)}, /* Kyrgyzstan Time */! {"kost", TZ, POS(48)}, /* Kosrae Time */! {"krast", DTZ, POS(28)}, /* Krasnoyarsk Summer Time */! {"krat", TZ, POS(32)}, /* Krasnoyarsk Standard Time */! {"kst", TZ, POS(36)}, /* Korea Standard Time */! {"lhdt", DTZ, POS(44)}, /* Lord Howe Daylight Time, Australia */! {"lhst", TZ, POS(42)}, /* Lord Howe Standard Time, Australia */! {"ligt", TZ, POS(40)}, /* From Melbourne, Australia */! {"lint", TZ, POS(56)}, /* Line Islands Time (Kiribati; +14 hours!) */! {"lkt", TZ, POS(24)}, /* Lanka Time */ {"m", UNITS, DTK_MONTH}, /* "month" for ISO input */! {"magst", DTZ, POS(48)}, /* Magadan Summer Time */! {"magt", TZ, POS(44)}, /* Magadan Time */ {"mar", MONTH, 3}, {"march", MONTH, 3},! {"mart", TZ, NEG(38)}, /* Marquesas Time */! {"mawt", TZ, POS(24)}, /* Mawson, Antarctica */ {"may", MONTH, 5},! {"mdt", DTZ, NEG(24)}, /* Mountain Daylight Time */! {"mest", DTZ, POS(8)}, /* Middle Europe Summer Time */! {"met", TZ, POS(4)}, /* Middle Europe Time */! {"metdst", DTZ, POS(8)}, /* Middle Europe Daylight Time */! {"mewt", TZ, POS(4)}, /* Middle Europe Winter Time */! {"mez", TZ, POS(4)}, /* Middle Europe Zone */! {"mht", TZ, POS(48)}, /* Kwajalein */ {"mm", UNITS, DTK_MINUTE}, /* "minute" for ISO input */! {"mmt", TZ, POS(26)}, /* Myannar Time */ {"mon", DOW, 1}, {"monday", DOW, 1}, #if 0 most #endif! {"mpt", TZ, POS(40)}, /* North Mariana Islands Time */! {"msd", DTZ, POS(16)}, /* Moscow Summer Time */! {"msk", TZ, POS(12)}, /* Moscow Time */! {"mst", TZ, NEG(28)}, /* Mountain Standard Time */! {"mt", TZ, POS(34)}, /* Moluccas Time */! {"mut", TZ, POS(16)}, /* Mauritius Island Time */! {"mvt", TZ, POS(20)}, /* Maldives Island Time */! {"myt", TZ, POS(32)}, /* Malaysia Time */ #if 0 ncst #endif! {"nct", TZ, POS(44)}, /* New Caledonia Time */! {"ndt", DTZ, NEG(10)}, /* Nfld. Daylight Time */! {"nft", TZ, NEG(14)}, /* Newfoundland Standard Time */! {"nor", TZ, POS(4)}, /* Norway Standard Time */ {"nov", MONTH, 11}, {"november", MONTH, 11},! {"novst", DTZ, POS(28)}, /* Novosibirsk Summer Time */! {"novt", TZ, POS(24)}, /* Novosibirsk Standard Time */ {NOW, RESERV, DTK_NOW}, /* current transaction time */! {"npt", TZ, POS(23)}, /* Nepal Standard Time (GMT-5:45) */! {"nst", TZ, NEG(14)}, /* Nfld. Standard Time */! {"nt", TZ, NEG(44)}, /* Nome Time */! {"nut", TZ, NEG(44)}, /* Niue Time */! {"nzdt", DTZ, POS(52)}, /* New Zealand Daylight Time */! {"nzst", TZ, POS(48)}, /* New Zealand Standard Time */! {"nzt", TZ, POS(48)}, /* New Zealand Time */ {"oct", MONTH, 10}, {"october", MONTH, 10},! {"omsst", DTZ, POS(28)}, /* Omsk Summer Time */! {"omst", TZ, POS(24)}, /* Omsk Time */ {"on", IGNORE_DTF, 0}, /* "on" (throwaway) */! {"pdt", DTZ, NEG(28)}, /* Pacific Daylight Time */ #if 0 pest #endif! {"pet", TZ, NEG(20)}, /* Peru Time */! {"petst", DTZ, POS(52)}, /* Petropavlovsk-Kamchatski Summer Time */! {"pett", TZ, POS(48)}, /* Petropavlovsk-Kamchatski Time */! {"pgt", TZ, POS(40)}, /* Papua New Guinea Time */! {"phot", TZ, POS(52)}, /* Phoenix Islands (Kiribati) Time */ #if 0 phst #endif! {"pht", TZ, POS(32)}, /* Philippine Time */! {"pkt", TZ, POS(20)}, /* Pakistan Time */ {"pm", AMPM, PM},! {"pmdt", DTZ, NEG(8)}, /* Pierre & Miquelon Daylight Time */ #if 0 pmst #endif! {"pont", TZ, POS(44)}, /* Ponape Time (Micronesia) */! {"pst", TZ, NEG(32)}, /* Pacific Standard Time */! {"pwt", TZ, POS(36)}, /* Palau Time */! {"pyst", DTZ, NEG(12)}, /* Paraguay Summer Time */! {"pyt", TZ, NEG(16)}, /* Paraguay Time */! {"ret", DTZ, POS(16)}, /* Reunion Island Time */ {"s", UNITS, DTK_SECOND}, /* "seconds" for ISO input */! {"sadt", DTZ, POS(42)}, /* S. Australian Dayl. Time */ #if 0 samst samt #endif! {"sast", TZ, POS(38)}, /* South Australian Std Time */ {"sat", DOW, 6}, {"saturday", DOW, 6}, #if 0 sbt #endif! {"sct", DTZ, POS(16)}, /* Mahe Island Time */ {"sep", MONTH, 9}, {"sept", MONTH, 9}, {"september", MONTH, 9},! {"set", TZ, NEG(4)}, /* Seychelles Time ?? */ #if 0 sgt #endif! {"sst", DTZ, POS(8)}, /* Swedish Summer Time */ {"sun", DOW, 0}, {"sunday", DOW, 0},! {"swt", TZ, POS(4)}, /* Swedish Winter Time */ #if 0 syot #endif {"t", ISOTIME, DTK_TIME}, /* Filler for ISO time fields */! {"tft", TZ, POS(20)}, /* Kerguelen Time */! {"that", TZ, NEG(40)}, /* Tahiti Time */ {"thu", DOW, 4}, {"thur", DOW, 4}, {"thurs", DOW, 4}, {"thursday", DOW, 4},! {"tjt", TZ, POS(20)}, /* Tajikistan Time */! {"tkt", TZ, NEG(40)}, /* Tokelau Time */! {"tmt", TZ, POS(20)}, /* Turkmenistan Time */ {TODAY, RESERV, DTK_TODAY}, /* midnight */ {TOMORROW, RESERV, DTK_TOMORROW}, /* tomorrow midnight */ #if 0 tost #endif! {"tot", TZ, POS(52)}, /* Tonga Time */ #if 0 tpt #endif! {"truk", TZ, POS(40)}, /* Truk Time */ {"tue", DOW, 2}, {"tues", DOW, 2}, {"tuesday", DOW, 2},! {"tvt", TZ, POS(48)}, /* Tuvalu Time */ #if 0 uct #endif! {"ulast", DTZ, POS(36)}, /* Ulan Bator Summer Time */! {"ulat", TZ, POS(32)}, /* Ulan Bator Time */ {"undefined", RESERV, DTK_INVALID}, /* pre-v6.1 invalid time */! {"ut", TZ, POS(0)},! {"utc", TZ, POS(0)},! {"uyst", DTZ, NEG(8)}, /* Uruguay Summer Time */! {"uyt", TZ, NEG(12)}, /* Uruguay Time */! {"uzst", DTZ, POS(24)}, /* Uzbekistan Summer Time */! {"uzt", TZ, POS(20)}, /* Uzbekistan Time */! {"vet", TZ, NEG(16)}, /* Venezuela Time */! {"vlast", DTZ, POS(44)}, /* Vladivostok Summer Time */! {"vlat", TZ, POS(40)}, /* Vladivostok Time */ #if 0 vust #endif! {"vut", TZ, POS(44)}, /* Vanuata Time */! {"wadt", DTZ, POS(32)}, /* West Australian DST */! {"wakt", TZ, POS(48)}, /* Wake Time */ #if 0 warst #endif! {"wast", TZ, POS(28)}, /* West Australian Std Time */! {"wat", TZ, NEG(4)}, /* West Africa Time */! {"wdt", DTZ, POS(36)}, /* West Australian DST */ {"wed", DOW, 3}, {"wednesday", DOW, 3}, {"weds", DOW, 3},! {"west", DTZ, POS(4)}, /* Western Europe Summer Time */! {"wet", TZ, POS(0)}, /* Western Europe */! {"wetdst", DTZ, POS(4)}, /* Western Europe Daylight Savings Time */! {"wft", TZ, POS(48)}, /* Wallis and Futuna Time */! {"wgst", DTZ, NEG(8)}, /* West Greenland Summer Time */! {"wgt", TZ, NEG(12)}, /* West Greenland Time */! {"wst", TZ, POS(32)}, /* West Australian Standard Time */ {"y", UNITS, DTK_YEAR}, /* "year" for ISO input */! {"yakst", DTZ, POS(40)}, /* Yakutsk Summer Time */! {"yakt", TZ, POS(36)}, /* Yakutsk Time */! {"yapt", TZ, POS(40)}, /* Yap Time (Micronesia) */! {"ydt", DTZ, NEG(32)}, /* Yukon Daylight Time */! {"yekst", DTZ, POS(24)}, /* Yekaterinburg Summer Time */! {"yekt", TZ, POS(20)}, /* Yekaterinburg Time */ {YESTERDAY, RESERV, DTK_YESTERDAY}, /* yesterday midnight */! {"yst", TZ, NEG(36)}, /* Yukon Standard Time */! {"z", TZ, POS(0)}, /* time zone tag per ISO-8601 */! {"zp4", TZ, NEG(16)}, /* UTC +4 hours. */! {"zp5", TZ, NEG(20)}, /* UTC +5 hours. */! {"zp6", TZ, NEG(24)}, /* UTC +6 hours. */! {ZULU, TZ, POS(0)}, /* UTC */ }; static datetkn deltatktbl[] = {--- 48,423 ---- aqtt arst #endif! {"art", TZ, -10800}, /* Argentina Time */ #if 0 ashst ast /* Atlantic Standard Time, Arabia Standard * Time, Acre Standard Time */ #endif! {"ast", TZ, -14400}, /* Atlantic Std Time (Canada) */ {"at", IGNORE_DTF, 0}, /* "at" (throwaway) */ {"aug", MONTH, 8}, {"august", MONTH, 8},! {"awsst", DTZ, 32400}, /* W. Australia */! {"awst", TZ, 28800}, /* W. Australia */! {"awt", DTZ, -10800},! {"azost", DTZ, 0}, /* Azores Summer Time */! {"azot", TZ, -3600}, /* Azores Time */! {"azst", DTZ, 18000}, /* Azerbaijan Summer Time */! {"azt", TZ, 14400}, /* Azerbaijan Time */ {DB_C, ADBC, BC}, /* "bc" for years < 0 */! {"bdst", TZ, 7200}, /* British Double Summer Time */! {"bdt", TZ, 21600}, /* Dacca */! {"bnt", TZ, 28800}, /* Brunei Darussalam Time */! {"bort", TZ, 28800}, /* Borneo Time (Indonesia) */ #if 0 bortst bost #endif! {"bot", TZ, -14400}, /* Bolivia Time */! {"bra", TZ, -10800}, /* Brazil Time */ #if 0 brst brt #endif! {"bst", DTZ, 3600}, /* British Summer Time */ #if 0! {"bst", TZ, -10800}, /* Brazil Standard Time */! {"bst", DTZ, -39600}, /* Bering Summer Time */ #endif! {"bt", TZ, 10800}, /* Baghdad Time */! {"btt", TZ, 21600}, /* Bhutan Time */! {"cadt", DTZ, 37800}, /* Central Australian DST */! {"cast", TZ, 34200}, /* Central Australian ST */! {"cat", TZ, -36000}, /* Central Alaska Time */! {"cct", TZ, 28800}, /* China Coast Time */ #if 0! {"cct", TZ, 23400}, /* Indian Cocos (Island) Time */ #endif! {"cdt", DTZ, -18000}, /* Central Daylight Time */! {"cest", DTZ, 7200}, /* Central European Dayl.Time */! {"cet", TZ, 3600}, /* Central European Time */! {"cetdst", DTZ, 7200}, /* Central European Dayl.Time */! {"chadt", DTZ, 49500}, /* Chatham Island Daylight Time (13:45) */! {"chast", TZ, 45900}, /* Chatham Island Time (12:45) */ #if 0 ckhst #endif! {"ckt", TZ, 43200}, /* Cook Islands Time */! {"clst", DTZ, -10800}, /* Chile Summer Time */! {"clt", TZ, -14400}, /* Chile Time */ #if 0 cost #endif! {"cot", TZ, -18000}, /* Columbia Time */! {"cst", TZ, -21600}, /* Central Standard Time */ {DCURRENT, RESERV, DTK_CURRENT}, /* "current" is always now */ #if 0 cvst #endif! {"cvt", TZ, 25200}, /* Christmas Island Time (Indian Ocean) */! {"cxt", TZ, 25200}, /* Christmas Island Time (Indian Ocean) */ {"d", UNITS, DTK_DAY}, /* "day of month" for ISO input */! {"davt", TZ, 25200}, /* Davis Time (Antarctica) */! {"ddut", TZ, 36000}, /* Dumont-d'Urville Time (Antarctica) */ {"dec", MONTH, 12}, {"december", MONTH, 12},! {"dnt", TZ, 3600}, /* Dansk Normal Tid */ {"dow", RESERV, DTK_DOW}, /* day of week */ {"doy", RESERV, DTK_DOY}, /* day of year */! {"dst", DTZMOD, SECS_PER_HOUR}, #if 0! {"dusst", DTZ, 21600}, /* Dushanbe Summer Time */ #endif! {"easst", DTZ, -18000}, /* Easter Island Summer Time */! {"east", TZ, -21600}, /* Easter Island Time */! {"eat", TZ, 10800}, /* East Africa Time */ #if 0! {"east", DTZ, 14400}, /* Indian Antananarivo Savings Time */! {"eat", TZ, 10800}, /* Indian Antananarivo Time */! {"ect", TZ, -14400}, /* Eastern Caribbean Time */! {"ect", TZ, -18000}, /* Ecuador Time */ #endif! {"edt", DTZ, -14400}, /* Eastern Daylight Time */! {"eest", DTZ, 10800}, /* Eastern Europe Summer Time */! {"eet", TZ, 7200}, /* East. Europe, USSR Zone 1 */! {"eetdst", DTZ, 10800}, /* Eastern Europe Daylight Time */! {"egst", DTZ, 0}, /* East Greenland Summer Time */! {"egt", TZ, -3600}, /* East Greenland Time */ #if 0 ehdt #endif {EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */! {"est", TZ, -18000}, /* Eastern Standard Time */ {"feb", MONTH, 2}, {"february", MONTH, 2},! {"fjst", DTZ, -46800}, /* Fiji Summer Time (13 hour offset!) */! {"fjt", TZ, -43200}, /* Fiji Time */! {"fkst", DTZ, -10800}, /* Falkland Islands Summer Time */! {"fkt", TZ, -7200}, /* Falkland Islands Time */ #if 0 fnst fnt #endif {"fri", DOW, 5}, {"friday", DOW, 5},! {"fst", TZ, 3600}, /* French Summer Time */! {"fwt", DTZ, 7200}, /* French Winter Time */! {"galt", TZ, -21600}, /* Galapagos Time */! {"gamt", TZ, -32400}, /* Gambier Time */! {"gest", DTZ, 18000}, /* Georgia Summer Time */! {"get", TZ, 14400}, /* Georgia Time */! {"gft", TZ, -10800}, /* French Guiana Time */ #if 0 ghst #endif! {"gilt", TZ, 43200}, /* Gilbert Islands Time */! {"gmt", TZ, 0}, /* Greenwish Mean Time */! {"gst", TZ, 36000}, /* Guam Std Time, USSR Zone 9 */! {"gyt", TZ, -14400}, /* Guyana Time */ {"h", UNITS, DTK_HOUR}, /* "hour" */ #if 0 hadt hast #endif! {"hdt", DTZ, -32400}, /* Hawaii/Alaska Daylight Time */ #if 0 hkst #endif! {"hkt", TZ, 28800}, /* Hong Kong Time */ #if 0! {"hmt", TZ, 10800}, /* Hellas ? ? */ hovst hovt #endif! {"hst", TZ, -36000}, /* Hawaii Std Time */ #if 0 hwt #endif! {"ict", TZ, 25200}, /* Indochina Time */! {"idle", TZ, 43200}, /* Intl. Date Line, East */! {"idlw", TZ, -43200}, /* Intl. Date Line, West */ #if 0 idt /* Israeli, Iran, Indian Daylight Time */ #endif {LATE, RESERV, DTK_LATE}, /* "infinity" reserved for "late time" */ {INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for bad time */! {"iot", TZ, 18000}, /* Indian Chagos Time */! {"irkst", DTZ, 32400}, /* Irkutsk Summer Time */! {"irkt", TZ, 28800}, /* Irkutsk Time */! {"irt", TZ, 12600}, /* Iran Time */ {"isodow", RESERV, DTK_ISODOW}, /* ISO day of week, Sunday == 7 */ #if 0 isst #endif! {"ist", TZ, 7200}, /* Israel */! {"it", TZ, 12600}, /* Iran Time */ {"j", UNITS, DTK_JULIAN}, {"jan", MONTH, 1}, {"january", MONTH, 1},! {"javt", TZ, 25200}, /* Java Time (07:00? see JT) */! {"jayt", TZ, 32400}, /* Jayapura Time (Indonesia) */ {"jd", UNITS, DTK_JULIAN},! {"jst", TZ, 32400}, /* Japan Std Time,USSR Zone 8 */! {"jt", TZ, 27000}, /* Java Time (07:30? see JAVT) */ {"jul", MONTH, 7}, {"julian", UNITS, DTK_JULIAN}, {"july", MONTH, 7}, {"jun", MONTH, 6}, {"june", MONTH, 6},! {"kdt", DTZ, 36000}, /* Korea Daylight Time */! {"kgst", DTZ, 21600}, /* Kyrgyzstan Summer Time */! {"kgt", TZ, 18000}, /* Kyrgyzstan Time */! {"kost", TZ, 43200}, /* Kosrae Time */! {"krast", DTZ, 25200}, /* Krasnoyarsk Summer Time */! {"krat", TZ, 28800}, /* Krasnoyarsk Standard Time */! {"kst", TZ, 32400}, /* Korea Standard Time */! {"lhdt", DTZ, 39600}, /* Lord Howe Daylight Time, Australia */! {"lhst", TZ, 37800}, /* Lord Howe Standard Time, Australia */! {"ligt", TZ, 36000}, /* From Melbourne, Australia */! {"lint", TZ, 50400}, /* Line Islands Time (Kiribati; +14 hours!) */! {"lkt", TZ, 21600}, /* Lanka Time */ {"m", UNITS, DTK_MONTH}, /* "month" for ISO input */! {"magst", DTZ, 43200}, /* Magadan Summer Time */! {"magt", TZ, 39600}, /* Magadan Time */ {"mar", MONTH, 3}, {"march", MONTH, 3},! {"mart", TZ, -34200}, /* Marquesas Time */! {"mawt", TZ, 21600}, /* Mawson, Antarctica */ {"may", MONTH, 5},! {"mdt", DTZ, -21600}, /* Mountain Daylight Time */! {"mest", DTZ, 7200}, /* Middle Europe Summer Time */! {"met", TZ, 3600}, /* Middle Europe Time */! {"metdst", DTZ, 7200}, /* Middle Europe Daylight Time */! {"mewt", TZ, 3600}, /* Middle Europe Winter Time */! {"mez", TZ, 3600}, /* Middle Europe Zone */! {"mht", TZ, 43200}, /* Kwajalein */ {"mm", UNITS, DTK_MINUTE}, /* "minute" for ISO input */! {"mmt", TZ, 23400}, /* Myannar Time */ {"mon", DOW, 1}, {"monday", DOW, 1}, #if 0 most #endif! {"mpt", TZ, 36000}, /* North Mariana Islands Time */! {"msd", DTZ, 14400}, /* Moscow Summer Time */! {"msk", TZ, 10800}, /* Moscow Time */! {"mst", TZ, -25200}, /* Mountain Standard Time */! {"mt", TZ, 30600}, /* Moluccas Time */! {"mut", TZ, 14400}, /* Mauritius Island Time */! {"mvt", TZ, 18000}, /* Maldives Island Time */! {"myt", TZ, 28800}, /* Malaysia Time */ #if 0 ncst #endif! {"nct", TZ, 39600}, /* New Caledonia Time */! {"ndt", DTZ, -9000}, /* Nfld. Daylight Time */! {"nft", TZ, -12600}, /* Newfoundland Standard Time */! {"nor", TZ, 3600}, /* Norway Standard Time */ {"nov", MONTH, 11}, {"november", MONTH, 11},! {"novst", DTZ, 25200}, /* Novosibirsk Summer Time */! {"novt", TZ, 21600}, /* Novosibirsk Standard Time */ {NOW, RESERV, DTK_NOW}, /* current transaction time */! {"npt", TZ, 20700}, /* Nepal Standard Time (GMT-5:45) */! {"nst", TZ, -12600}, /* Nfld. Standard Time */! {"nt", TZ, -39600}, /* Nome Time */! {"nut", TZ, -39600}, /* Niue Time */! {"nzdt", DTZ, 46800}, /* New Zealand Daylight Time */! {"nzst", TZ, 43200}, /* New Zealand Standard Time */! {"nzt", TZ, 43200}, /* New Zealand Time */ {"oct", MONTH, 10}, {"october", MONTH, 10},! {"omsst", DTZ, 25200}, /* Omsk Summer Time */! {"omst", TZ, 21600}, /* Omsk Time */ {"on", IGNORE_DTF, 0}, /* "on" (throwaway) */! {"pdt", DTZ, -25200}, /* Pacific Daylight Time */ #if 0 pest #endif! {"pet", TZ, -18000}, /* Peru Time */! {"petst", DTZ, 46800}, /* Petropavlovsk-Kamchatski Summer Time */! {"pett", TZ, 43200}, /* Petropavlovsk-Kamchatski Time */! {"pgt", TZ, 36000}, /* Papua New Guinea Time */! {"phot", TZ, 46800}, /* Phoenix Islands (Kiribati) Time */ #if 0 phst #endif! {"pht", TZ, 28800}, /* Philippine Time */! {"pkt", TZ, 18000}, /* Pakistan Time */ {"pm", AMPM, PM},! {"pmdt", DTZ, -7200}, /* Pierre & Miquelon Daylight Time */ #if 0 pmst #endif! {"pont", TZ, 39600}, /* Ponape Time (Micronesia) */! {"pst", TZ, -28800}, /* Pacific Standard Time */! {"pwt", TZ, 32400}, /* Palau Time */! {"pyst", DTZ, -10800}, /* Paraguay Summer Time */! {"pyt", TZ, -14400}, /* Paraguay Time */! {"ret", DTZ, 14400}, /* Reunion Island Time */ {"s", UNITS, DTK_SECOND}, /* "seconds" for ISO input */! {"sadt", DTZ, 37800}, /* S. Australian Dayl. Time */ #if 0 samst samt #endif! {"sast", TZ, 34200}, /* South Australian Std Time */ {"sat", DOW, 6}, {"saturday", DOW, 6}, #if 0 sbt #endif! {"sct", DTZ, 14400}, /* Mahe Island Time */ {"sep", MONTH, 9}, {"sept", MONTH, 9}, {"september", MONTH, 9},! {"set", TZ, -3600}, /* Seychelles Time ?? */ #if 0 sgt #endif! {"sst", DTZ, 7200}, /* Swedish Summer Time */ {"sun", DOW, 0}, {"sunday", DOW, 0},! {"swt", TZ, 3600}, /* Swedish Winter Time */ #if 0 syot #endif {"t", ISOTIME, DTK_TIME}, /* Filler for ISO time fields */! {"tft", TZ, 18000}, /* Kerguelen Time */! {"that", TZ, -36000}, /* Tahiti Time */ {"thu", DOW, 4}, {"thur", DOW, 4}, {"thurs", DOW, 4}, {"thursday", DOW, 4},! {"tjt", TZ, 18000}, /* Tajikistan Time */! {"tkt", TZ, -36000}, /* Tokelau Time */! {"tmt", TZ, 18000}, /* Turkmenistan Time */ {TODAY, RESERV, DTK_TODAY}, /* midnight */ {TOMORROW, RESERV, DTK_TOMORROW}, /* tomorrow midnight */ #if 0 tost #endif! {"tot", TZ, 46800}, /* Tonga Time */ #if 0 tpt #endif! {"truk", TZ, 36000}, /* Truk Time */ {"tue", DOW, 2}, {"tues", DOW, 2}, {"tuesday", DOW, 2},! {"tvt", TZ, 43200}, /* Tuvalu Time */ #if 0 uct #endif! {"ulast", DTZ, 32400}, /* Ulan Bator Summer Time */! {"ulat", TZ, 28800}, /* Ulan Bator Time */ {"undefined", RESERV, DTK_INVALID}, /* pre-v6.1 invalid time */! {"ut", TZ, 0},! {"utc", TZ, 0},! {"uyst", DTZ, -7200}, /* Uruguay Summer Time */! {"uyt", TZ, -10800}, /* Uruguay Time */! {"uzst", DTZ, 21600}, /* Uzbekistan Summer Time */! {"uzt", TZ, 18000}, /* Uzbekistan Time */! {"vet", TZ, -14400}, /* Venezuela Time */! {"vlast", DTZ, 39600}, /* Vladivostok Summer Time */! {"vlat", TZ, 36000}, /* Vladivostok Time */ #if 0 vust #endif! {"vut", TZ, 39600}, /* Vanuata Time */! {"wadt", DTZ, 28800}, /* West Australian DST */! {"wakt", TZ, 43200}, /* Wake Time */ #if 0 warst #endif! {"wast", TZ, 25200}, /* West Australian Std Time */! {"wat", TZ, -3600}, /* West Africa Time */! {"wdt", DTZ, 32400}, /* West Australian DST */ {"wed", DOW, 3}, {"wednesday", DOW, 3}, {"weds", DOW, 3},! {"west", DTZ, 3600}, /* Western Europe Summer Time */! {"wet", TZ, 0}, /* Western Europe */! {"wetdst", DTZ, 3600}, /* Western Europe Daylight Savings Time */! {"wft", TZ, 43200}, /* Wallis and Futuna Time */! {"wgst", DTZ, -7200}, /* West Greenland Summer Time */! {"wgt", TZ, -10800}, /* West Greenland Time */! {"wst", TZ, 28800}, /* West Australian Standard Time */ {"y", UNITS, DTK_YEAR}, /* "year" for ISO input */! {"yakst", DTZ, 36000}, /* Yakutsk Summer Time */! {"yakt", TZ, 32400}, /* Yakutsk Time */! {"yapt", TZ, 36000}, /* Yap Time (Micronesia) */! {"ydt", DTZ, -28800}, /* Yukon Daylight Time */! {"yekst", DTZ, 21600}, /* Yekaterinburg Summer Time */! {"yekt", TZ, 18000}, /* Yekaterinburg Time */ {YESTERDAY, RESERV, DTK_YESTERDAY}, /* yesterday midnight */! {"yst", TZ, -32400}, /* Yukon Standard Time */! {"z", TZ, 0}, /* time zone tag per ISO-8601 */! {"zp4", TZ, -14400}, /* UTC +4 hours. */! {"zp5", TZ, -18000}, /* UTC +5 hours. */! {"zp6", TZ, -21600}, /* UTC +6 hours. */! {ZULU, TZ, 0}, /* UTC */ }; static datetkn deltatktbl[] = {*************** datebsearch(char *key, datetkn *base, un*** 521,529 **** while (last >= base) { position = base + ((last - base) >> 1);! result = key[0] - position->token[0]; if (result == 0) { result = strncmp(key, position->token, TOKMAXLEN); if (result == 0) return position;--- 514,524 ---- while (last >= base) { position = base + ((last - base) >> 1);! /* precheck the first character for a bit of extra speed */! result = (int) key[0] - (int) position->token[0]; if (result == 0) {+ /* use strncmp so that we match truncated tokens */ result = strncmp(key, position->token, TOKMAXLEN); if (result == 0) return position;*************** DecodeUnits(int field, char *lowtoken, i*** 547,552 ****--- 542,548 ---- int type; datetkn *tp;+ /* use strncmp so that we match truncated tokens */ if (deltacache[field] != NULL && strncmp(lowtoken, deltacache[field]->token, TOKMAXLEN) == 0) tp = deltacache[field];*************** DecodeUnits(int field, char *lowtoken, i*** 561,570 **** else { type = tp->type;! if (type == TZ || type == DTZ)! *val = FROMVAL(tp);! else! *val = tp->value; } return type;--- 557,563 ---- else { type = tp->type;! *val = tp->value; } return type;*************** DecodeSpecial(int field, char *lowtoken,*** 650,655 ****--- 643,649 ---- int type; datetkn *tp;+ /* use strncmp so that we match truncated tokens */ if (datecache[field] != NULL && strncmp(lowtoken, datecache[field]->token, TOKMAXLEN) == 0) tp = datecache[field];*************** DecodeSpecial(int field, char *lowtoken,*** 668,685 **** else { type = tp->type;! switch (type)! {! case TZ:! case DTZ:! case DTZMOD:! *val = FROMVAL(tp);! break;!! default:! *val = tp->value;! break;! } } return type;--- 662,668 ---- else { type = tp->type;! *val = tp->value; } return type;*************** DecodePosixTimezone(char *str, int *tzp)*** 1656,1662 **** { case DTZ: case TZ:! *tzp = (val * MINS_PER_HOUR) - tz; break; default:--- 1639,1645 ---- { case DTZ: case TZ:! *tzp = -(val + tz); break; default:*************** DecodeDateTime(char **field, int *ftype,*** 2308,2314 **** tm->tm_isdst = 1; if (tzp == NULL) return -1;! *tzp += val * MINS_PER_HOUR; break; case DTZ:--- 2291,2297 ---- tm->tm_isdst = 1; if (tzp == NULL) return -1;! *tzp -= val; break; case DTZ:*************** DecodeDateTime(char **field, int *ftype,*** 2321,2327 **** tm->tm_isdst = 1; if (tzp == NULL) return -1;! *tzp = val * MINS_PER_HOUR; ftype[i] = DTK_TZ; break;--- 2304,2310 ---- tm->tm_isdst = 1; if (tzp == NULL) return -1;! *tzp = -val; ftype[i] = DTK_TZ; break;*************** DecodeDateTime(char **field, int *ftype,*** 2329,2335 **** tm->tm_isdst = 0; if (tzp == NULL) return -1;! *tzp = val * MINS_PER_HOUR; ftype[i] = DTK_TZ; break;--- 2312,2318 ---- tm->tm_isdst = 0; if (tzp == NULL) return -1;! *tzp = -val; ftype[i] = DTK_TZ; break;*************** PGTYPEStimestamp_defmt_scan(char **str,*** 3000,3024 **** pfmt++; scan_type = PGTYPES_TYPE_STRING_MALLOCED; err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);!! /*! * XXX use DecodeSpecial instead ? - it's declared static but! * the arrays as well. :-(! */! for (j = 0; !err && j < szdatetktbl; j++) {! if (pg_strcasecmp(datetktbl[j].token, scan_val.str_val) == 0) {! /*! * tz calculates the offset for the seconds, the! * timezone value of the datetktbl table is in quarter! * hours! */! *tz = -15 * MINS_PER_HOUR * datetktbl[j].value;! break; } }- free(scan_val.str_val); break; case '+': /* XXX */--- 2983,3008 ---- pfmt++; scan_type = PGTYPES_TYPE_STRING_MALLOCED; err = pgtypes_defmt_scan(&scan_val, scan_type, &pstr, pfmt);! if (!err) {! /*! * XXX use DecodeSpecial instead? Do we need strcasecmp! * here?! */! err = 1;! for (j = 0; j < szdatetktbl; j++) {! if ((datetktbl[j].type == TZ || datetktbl[j].type == DTZ) &&! pg_strcasecmp(datetktbl[j].token,! scan_val.str_val) == 0)! {! *tz = -datetktbl[j].value;! err = 0;! break;! } }+ free(scan_val.str_val); } break; case '+': /* XXX */

pgsql-hackers by date:

Previous

From:Andres Freund
Date:
Subject:Re: lwlock contention with SSI

Next

From:Peter Geoghegan
Date:
Subject:Re: Promise index tuples for UPSERT

By continuing to browse this website, you agree to the use of cookies. Go to Privacy Policy.

Re: Proposal for better support of time-varying timezone abbreviations - Mailing list pgsql-hackers (2024)
Top Articles
NTV : July 13, 2024 10:11pm-11:41pm MSK : Free Borrow & Streaming : Internet Archive
Convert each measurement to the specified units. Round to nearest degree. ( 6.4 B ) 50 degrees Celsius to Fahrenheit | Numerade
Cpmc Mission Bernal Campus & Orthopedic Institute Photos
Katie Pavlich Bikini Photos
Po Box 7250 Sioux Falls Sd
Enrique Espinosa Melendez Obituary
Senior Tax Analyst Vs Master Tax Advisor
The Powers Below Drop Rate
Does Pappadeaux Pay Weekly
What is a basic financial statement?
Jcpenney At Home Associate Kiosk
Skylar Vox Bra Size
Amelia Bissoon Wedding
2024 Non-Homestead Millage - Clarkston Community Schools
Wisconsin Women's Volleyball Team Leaked Pictures
Summer Rae Boyfriend Love Island – Just Speak News
What is Cyber Big Game Hunting? - CrowdStrike
Busted Barren County Ky
Unit 33 Quiz Listening Comprehension
Bank Of America Financial Center Irvington Photos
/Www.usps.com/International/Passports.htm
Juicy Deal D-Art
Tyrone Unblocked Games Bitlife
Parc Soleil Drowning
Does Hunter Schafer Have A Dick
Www Pointclickcare Cna Login
Turbo Tenant Renter Login
Geico Car Insurance Review 2024
Ardie From Something Was Wrong Podcast
Jesus Calling Feb 13
91 Octane Gas Prices Near Me
Kids and Adult Dinosaur Costume
Manuel Pihakis Obituary
new haven free stuff - craigslist
Sun Haven Pufferfish
Kstate Qualtrics
Frostbite Blaster
Shoreone Insurance A.m. Best Rating
To Give A Guarantee Promise Figgerits
Otter Bustr
Aliciabibs
Htb Forums
Bartow Qpublic
Random Animal Hybrid Generator Wheel
M&T Bank
Hello – Cornerstone Chapel
Ajpw Sugar Glider Worth
2000 Ford F-150 for sale - Scottsdale, AZ - craigslist
Craigslist Free Cats Near Me
Ciara Rose Scalia-Hirschman
De Donde Es El Area +63
Provincial Freeman (Toronto and Chatham, ON: Mary Ann Shadd Cary (October 9, 1823 – June 5, 1893)), November 3, 1855, p. 1
Latest Posts
Article information

Author: Van Hayes

Last Updated:

Views: 6437

Rating: 4.6 / 5 (46 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Van Hayes

Birthday: 1994-06-07

Address: 2004 Kling Rapid, New Destiny, MT 64658-2367

Phone: +512425013758

Job: National Farming Director

Hobby: Reading, Polo, Genealogy, amateur radio, Scouting, Stand-up comedy, Cryptography

Introduction: My name is Van Hayes, I am a thankful, friendly, smiling, calm, powerful, fine, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.