📄 dt.c
字号:
*result = tm->tm_mon; break; case DTK_QUARTER: *result = (tm->tm_mon / 4) + 1; break; case DTK_YEAR: *result = tm->tm_year; break; case DTK_DECADE: *result = (tm->tm_year / 10); break; case DTK_CENTURY: *result = (tm->tm_year / 100); break; case DTK_MILLENIUM: *result = (tm->tm_year / 1000); break; default: elog(ERROR, "Datetime units '%s' not supported", lowunits); *result = 0; } } else if (type == RESERV) { switch (val) { case DTK_EPOCH: DATETIME_EPOCH(*result); *result = dt - SetDateTime(*result); break; case DTK_DOW: if (datetime2tm(dt, &tz, tm, &fsec, &tzn) != 0) elog(ERROR, "Unable to encode datetime", NULL); *result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); break; case DTK_DOY: if (datetime2tm(dt, &tz, tm, &fsec, &tzn) != 0) elog(ERROR, "Unable to encode datetime", NULL); *result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(tm->tm_year, 1, 1) + 1); break; default: elog(ERROR, "Datetime units '%s' not supported", lowunits); *result = 0; } } else { elog(ERROR, "Datetime units '%s' not recognized", lowunits); *result = 0; } } return result;} /* datetime_part() *//* timespan_part() * Extract specified field from timespan. */float64timespan_part(text *units, TimeSpan *timespan){ float64 result; int type, val; int i; char *up, *lp, lowunits[MAXDATELEN + 1]; double fsec; struct tm tt, *tm = &tt; if ((!PointerIsValid(units)) || (!PointerIsValid(timespan))) return NULL; result = palloc(sizeof(float64data)); up = VARDATA(units); lp = lowunits; for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++) *lp++ = tolower(*up++); *lp = '\0'; type = DecodeUnits(0, lowunits, &val); if (type == IGNORE) type = DecodeSpecial(0, lowunits, &val);#ifdef DATEDEBUG if (type == IGNORE) strcpy(lowunits, "(unknown)"); printf("timespan_part- units %s type=%d value=%d\n", lowunits, type, val);#endif if (TIMESPAN_IS_INVALID(*timespan)) {#if NOT_USED elog(ERROR, "Timespan is not finite", NULL);#endif *result = 0; } else if (type == UNITS) { if (timespan2tm(*timespan, tm, &fsec) == 0) { switch (val) { case DTK_MICROSEC: *result = (fsec * 1000000); break; case DTK_MILLISEC: *result = (fsec * 1000); break; case DTK_SECOND: *result = (tm->tm_sec + fsec); break; case DTK_MINUTE: *result = tm->tm_min; break; case DTK_HOUR: *result = tm->tm_hour; break; case DTK_DAY: *result = tm->tm_mday; break; case DTK_MONTH: *result = tm->tm_mon; break; case DTK_QUARTER: *result = (tm->tm_mon / 4) + 1; break; case DTK_YEAR: *result = tm->tm_year; break; case DTK_DECADE: *result = (tm->tm_year / 10); break; case DTK_CENTURY: *result = (tm->tm_year / 100); break; case DTK_MILLENIUM: *result = (tm->tm_year / 1000); break; default: elog(ERROR, "Timespan units '%s' not yet supported", units); result = NULL; } } else { elog(NOTICE, "Timespan out of range", NULL); *result = 0; } } else if ((type == RESERV) && (val == DTK_EPOCH)) { *result = timespan->time; if (timespan->month != 0) { *result += ((365.25 * 86400) * (timespan->month / 12)); *result += ((30 * 86400) * (timespan->month % 12)); } } else { elog(ERROR, "Timespan units '%s' not recognized", units); *result = 0; } return result;} /* timespan_part() *//* datetime_zone() * Encode datetime type with specified time zone. */text *datetime_zone(text *zone, DateTime *datetime){ text *result; DateTime dt; int tz; int type, val; int i; char *up, *lp, lowzone[MAXDATELEN + 1]; char *tzn, upzone[MAXDATELEN + 1]; double fsec; struct tm tt, *tm = &tt; char buf[MAXDATELEN + 1]; int len; if ((!PointerIsValid(zone)) || (!PointerIsValid(datetime))) return NULL; up = VARDATA(zone); lp = lowzone; for (i = 0; i < (VARSIZE(zone) - VARHDRSZ); i++) *lp++ = tolower(*up++); *lp = '\0'; type = DecodeSpecial(0, lowzone, &val);#ifdef DATEDEBUG if (type == IGNORE) strcpy(lowzone, "(unknown)"); printf("datetime_zone- zone %s type=%d value=%d\n", lowzone, type, val);#endif if (DATETIME_NOT_FINITE(*datetime)) { /* * could return null but Postgres doesn't like that currently. - * tgl 97/06/12 */ elog(ERROR, "Datetime is not finite", NULL); result = NULL; } else if ((type == TZ) || (type == DTZ)) { tm->tm_isdst = ((type == DTZ) ? 1 : 0); tz = val * 60; dt = (DATETIME_IS_RELATIVE(*datetime) ? SetDateTime(*datetime) : *datetime); dt = dt2local(dt, tz); if (datetime2tm(dt, NULL, tm, &fsec, NULL) != 0) elog(ERROR, "Datetime not legal", NULL); up = upzone; lp = lowzone; for (i = 0; *lp != '\0'; i++) *up++ = toupper(*lp++); *up = '\0'; tzn = upzone; EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf); len = (strlen(buf) + VARHDRSZ); result = palloc(len); VARSIZE(result) = len; memmove(VARDATA(result), buf, (len - VARHDRSZ)); } else { elog(ERROR, "Time zone '%s' not recognized", lowzone); result = NULL; } return result;} /* datetime_zone() *//***************************************************************************** * PRIVATE ROUTINES * *****************************************************************************//* definitions for squeezing values into "value" */#define ABS_SIGNBIT (char) 0200#define VALMASK (char) 0177#define NEG(n) ((n)|ABS_SIGNBIT)#define SIGNEDCHAR(c) ((c)&ABS_SIGNBIT? -((c)&VALMASK): (c))#define FROMVAL(tp) (-SIGNEDCHAR((tp)->value) * 10) /* uncompress */#define TOVAL(tp, v) ((tp)->value = ((v) < 0? NEG((-(v))/10): (v)/10))/* * to keep this table reasonably small, we divide the lexval for TZ and DTZ * entries by 10 and truncate the text field at MAXTOKLEN characters. * the text field is not guaranteed to be NULL-terminated. */static datetkn datetktbl[] = {/* text token lexval */ {EARLY, RESERV, DTK_EARLY}, /* "-infinity" reserved for "early time" */ {"acsst", DTZ, 63}, /* Cent. Australia */ {"acst", TZ, 57}, /* Cent. Australia */ {DA_D, ADBC, AD}, /* "ad" for years >= 0 */ {"abstime", IGNORE, 0}, /* "abstime" for pre-v6.1 "Invalid * Abstime" */ {"adt", DTZ, NEG(18)}, /* Atlantic Daylight Time */ {"aesst", DTZ, 66}, /* E. Australia */ {"aest", TZ, 60}, /* Australia Eastern Std Time */ {"ahst", TZ, NEG(60)}, /* Alaska-Hawaii Std Time */ {"allballs", RESERV, DTK_ZULU}, /* 00:00:00 */ {"am", AMPM, AM}, {"apr", MONTH, 4}, {"april", MONTH, 4}, {"ast", TZ, NEG(24)}, /* Atlantic Std Time (Canada) */ {"at", IGNORE, 0}, /* "at" (throwaway) */ {"aug", MONTH, 8}, {"august", MONTH, 8}, {"awsst", DTZ, 54}, /* W. Australia */ {"awst", TZ, 48}, /* W. Australia */ {DB_C, ADBC, BC}, /* "bc" for years < 0 */ {"bst", TZ, 6}, /* British Summer Time */ {"bt", TZ, 18}, /* Baghdad Time */ {"cadt", DTZ, 63}, /* Central Australian DST */ {"cast", TZ, 57}, /* Central Australian ST */ {"cat", TZ, NEG(60)}, /* Central Alaska Time */ {"cct", TZ, 48}, /* China Coast */ {"cdt", DTZ, NEG(30)}, /* Central Daylight Time */ {"cet", TZ, 6}, /* Central European Time */ {"cetdst", DTZ, 12}, /* Central European Dayl.Time */ {"cst", TZ, NEG(36)}, /* Central Standard Time */ {DCURRENT, RESERV, DTK_CURRENT}, /* "current" is always now */ {"dec", MONTH, 12}, {"december", MONTH, 12}, {"dnt", TZ, 6}, /* Dansk Normal Tid */ {"dow", RESERV, DTK_DOW}, /* day of week */ {"doy", RESERV, DTK_DOY}, /* day of year */ {"dst", DTZMOD, 6}, {"east", TZ, NEG(60)}, /* East Australian Std Time */ {"edt", DTZ, NEG(24)}, /* Eastern Daylight Time */ {"eet", TZ, 12}, /* East. Europe, USSR Zone 1 */ {"eetdst", DTZ, 18}, /* Eastern Europe */ {EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */#if USE_AUSTRALIAN_RULES {"est", TZ, 60}, /* Australia Eastern Std Time */#else {"est", TZ, NEG(30)}, /* Eastern Standard Time */#endif {"feb", MONTH, 2}, {"february", MONTH, 2}, {"fri", DOW, 5}, {"friday", DOW, 5}, {"fst", TZ, 6}, /* French Summer Time */ {"fwt", DTZ, 12}, /* French Winter Time */ {"gmt", TZ, 0}, /* Greenwish Mean Time */ {"gst", TZ, 60}, /* Guam Std Time, USSR Zone 9 */ {"hdt", DTZ, NEG(54)}, /* Hawaii/Alaska */ {"hmt", DTZ, 18}, /* Hellas ? ? */ {"hst", TZ, NEG(60)}, /* Hawaii Std Time */ {"idle", TZ, 72}, /* Intl. Date Line, East */ {"idlw", TZ, NEG(72)}, /* Intl. Date Line, West */ {LATE, RESERV, DTK_LATE}, /* "infinity" reserved for "late time" */ {INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for invalid time */ {"ist", TZ, 12}, /* Israel */ {"it", TZ, 21}, /* Iran Time */ {"jan", MONTH, 1}, {"january", MONTH, 1}, {"jst", TZ, 54}, /* Japan Std Time,USSR Zone 8 */ {"jt", TZ, 45}, /* Java Time */ {"jul", MONTH, 7}, {"july", MONTH, 7}, {"jun", MONTH, 6}, {"june", MONTH, 6}, {"kst", TZ, 54}, /* Korea Standard Time */ {"ligt", TZ, 60}, /* From Melbourne, Australia */ {"mar", MONTH, 3}, {"march", MONTH, 3}, {"may", MONTH, 5}, {"mdt", DTZ, NEG(36)}, /* Mountain Daylight Time */ {"mest", DTZ, 12}, /* Middle Europe Summer Time */ {"met", TZ, 6}, /* Middle Europe Time */ {"metdst", DTZ, 12}, /* Middle Europe Daylight Time */ {"mewt", TZ, 6}, /* Middle Europe Winter Time */ {"mez", TZ, 6}, /* Middle Europe Zone */ {"mon", DOW, 1}, {"monday", DOW, 1}, {"mst", TZ, NEG(42)}, /* Mountain Standard Time */ {"mt", TZ, 51}, /* Moluccas Time */ {"ndt", DTZ, NEG(15)}, /* Nfld. Daylight Time */ {"nft", TZ, NEG(21)}, /* Newfoundland Standard Time */ {"nor", TZ, 6}, /* Norway Standard Time */ {"nov", MONTH, 11}, {"november", MONTH, 11}, {NOW, RESERV, DTK_NOW}, /* current transaction time */ {"nst", TZ, NEG(21)}, /* Nfld. Standard Time */ {"nt", TZ, NEG(66)}, /* Nome Time */ {"nzdt", DTZ, 78}, /* New Zealand Daylight Time */ {"nzst", TZ, 72}, /* New Zealand Standard Time */ {"nzt", TZ, 72}, /* New Zealand Time */ {"oct", MONTH, 10}, {"october", MONTH, 10}, {"on", IGNORE, 0}, /* "on" (throwaway) */ {"pdt", DTZ, NEG(42)}, /* Pacific Daylight Time */ {"pm", AMPM, PM}, {"pst", TZ, NEG(48)}, /* Pacific Standard Time */ {"sadt", DTZ, 63}, /* S. Australian Dayl. Time */ {"sast", TZ, 57}, /* South Australian Std Time */ {"sat", DOW, 6}, {"saturday", DOW, 6}, {"sep", MONTH, 9}, {"sept", MONTH, 9}, {"september", MONTH, 9}, {"set", TZ, NEG(6)}, /* Seychelles Time ?? */ {"sst", DTZ, 12}, /* Swedish Summer Time */ {"sun", DOW, 0}, {"sunday", DOW, 0}, {"swt", TZ, 6}, /* Swedish Winter Time */ {"thu", DOW, 4}, {"thur", DOW, 4}, {"thurs", DOW, 4}, {"thursday", DOW, 4}, {TODAY, RESERV, DTK_TODAY}, /* midnight */ {TOMORROW, RESERV, DTK_TOMORROW}, /* tomorrow midnight */ {"tue", DOW, 2}, {"tues", DOW, 2}, {"tuesday", DOW, 2}, {"undefined", RESERV, DTK_INVALID}, /* "undefined" pre-v6.1 invalid * time */ {"ut", TZ, 0}, {"utc", TZ, 0}, {"wadt", DTZ, 48}, /* West Australian DST */ {"wast", TZ, 42}, /* West Australian Std Time */ {"wat", TZ, NEG(6)}, /* West Africa Time */ {"wdt", DTZ, 54}, /* West Australian DST */ {"wed", DOW, 3}, {"wednesday", DOW, 3}, {"weds", DOW, 3}, {"wet", TZ, 0}, /* Western Europe */ {"wetdst", DTZ, 6}, /* Western Europe */ {"wst", TZ, 48}, /* West Australian Std Time */ {"ydt", DTZ, NEG(48)}, /* Yukon Daylight Time */ {YESTERDAY, RESERV, DTK_YESTERDAY}, /* yesterday midnight */ {"yst", TZ, NEG(54)}, /* Yukon Standard Time */ {"zp4", TZ, NEG(24)}, /* GMT +4 hours. */ {"zp5", TZ, NEG(30)}, /* GMT +5 hours. */ {"zp6", TZ, NEG(36)}, /* GMT +6 hours. */ {"z", RESERV, DTK_ZULU}, /* 00:00:00 */ {ZULU, RESERV, DTK_ZULU}, /* 00:00:00 */};static unsigned int szdatetktbl = sizeof datetktbl / sizeof datetktbl[0];static datetkn deltatktbl[] = {/* text token lexval */ {"@", IGNORE, 0}, /* postgres relative time prefix */ {DAGO, AGO, 0}, /* "ago" indicates negative time offset */ {"c", UNITS, DTK_CENTURY}, /* "century" relative time units */ {"cent", UNITS, DTK_CENTURY}, /* "century" relative time units */ {"centuries", UNITS, DTK_CENTURY}, /* "centuries" relative time units */ {DCENTURY, UNITS, DTK_CENTURY}, /* "century" relative time units */ {"d", UNITS, DTK_DAY}, /* "day" relative time units */ {DDAY, UNITS, DTK_DAY}, /* "day" relative time units */ {"days", UNITS, DTK_DAY}, /* "days" relative time units */ {"dec", UNITS, DTK_DECADE}, /* "decade" relative time units */ {"decs", UNITS, DTK_DECADE},/* "decades" relative time units */ {DDECADE, UNITS, DTK_DECADE}, /* "decade" relative time units */ {"decades", UNITS, DTK_DECADE}, /* "decades" relative time units */ {"h", UNITS, DTK_HOUR}, /* "hour" relative time units */ {DHOUR, UNITS, DTK_HOUR}, /* "hour" relative time units */ {"hours", UNITS, DTK_HOUR}, /* "hours" relative time units */ {"hr", UNITS, DTK_HOUR}, /* "hour" relative time units */ {"hrs", UNITS, DTK_HOUR}, /* "hours" relative time units */ {INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for invalid * time */ {"m", UNITS, DTK_MINUTE}, /* "minute" relative time units */ {"microsecon", UNITS, DTK_MICROSEC}, /* "microsecond" relative * time units */ {"mil", UNITS, DTK_MILLENIUM}, /* "millenium" relative time units */ {"mils", UNITS, DTK_MILLENIUM}, /* "millenia" relative time units */ {"millenia", UNITS, DTK_MILLENIUM}, /* "millenia" relative time units */ {DMILLENIUM, UNITS, DTK_MILLENIUM}, /* "millenium" relative time units */ {"millisecon", UNITS, DTK_MILLISEC}, /* relative time units */ {"min", UNITS, DTK_MINUTE}, /* "minute" relative time units */ {"mins", UNITS, DTK_MINUTE},/* "minutes" relative time units */ {"mins", UNITS, DTK_MINUTE},/* "minutes" relative time units */ {DMINUTE, UNITS, DTK_MINUTE}, /* "minute" relative time units */ {"minutes", UNITS, DTK_MINUTE}, /* "minutes" relative time units */ {"mon", UNITS, DTK_MONTH}, /* "months" relative time units */ {"mons", UNITS, DTK_MONTH}, /* "months" relative time units */ {DMONTH, UNITS, DTK_MONTH}, /* "month" relative time units */ {"months", UNITS, DTK_MONTH}, {"ms", UNITS, DTK_MILLISEC}, {"msec", UNITS, DTK_MILLISEC}, {DMILLISEC, UNITS, DTK_MILLISEC}, {"mseconds", UNITS, DTK_MILLISEC}, {"msecs", UNITS, DTK_MILLISEC}, {"qtr", UNITS, DTK_QUARTER},/* "quarter" relative time */ {DQUARTER, UNITS, DTK_QUARTER}, /* "quarter" relative time */ {"reltime", IGNORE, 0}, /* for pre-v6.1 "Undefined Reltime" */ {"s", UNITS, DTK_SECOND}, {"sec", UNITS, DTK_SECOND}, {DSECOND, UNITS, DTK_SECOND}, {"seconds", UNITS, DTK_SECOND}, {"secs", UNITS, DTK_SECOND}, {DTIMEZONE, UNITS, DTK_TZ}, /* "timezone" time offset */ {"tz", UNITS, DTK_TZ}, /* "timezone" time offset */ {"tz_hour", UNITS, DTK_TZ_HOUR}, /* timezone hour units */ {"tz_minute", UNITS, DTK_TZ_MINUTE}, /* timezone minutes units */ {"undefined", RESERV, DTK_INVALID}, /* pre-v6.1 invalid time */ {"us", UNITS, DTK_MICROSEC},/* "microsecond" relative time units */ {"usec", UNITS, DTK_MICROSEC}, /* "microsecond" relative time * units */ {DMICROSEC, UNITS, DTK_MICROSEC}, /* "microsecond" relative time * units */ {"useconds", UNITS, DTK_MICROSEC}, /* "microseconds" relative time * units */ {"usecs", UNITS, DTK_MICROSEC}, /* "microseconds" relative time * units */ {"w", UNITS, DTK_WEEK}, /* "week" relative time units */ {DWEEK, UNITS, DTK_WEEK}, /* "week" relative time units */ {"weeks", UNITS, DTK_WEEK}, /* "weeks" relative time units */ {"y", UNITS, DTK_YEAR}, /* "year" relative time units */ {DYEAR, UNITS, DTK_YEAR}, /* "year" relative time units */ {"years", UNITS, DTK_YEAR}, /* "years" relative time units */ {"yr", UNITS, DTK_YEAR}, /* "year" relative time units */ {"yrs", UNITS, DTK_YEAR}, /* "years" relative time units */};static unsigned int szdeltatktbl = sizeof deltatktbl / sizeof deltatktbl[0];#if USE_DATE_CACHEdatetkn *datecache[MAXDATEFIELDS] = {NULL};datetkn *deltacache[MAXDATEFIELDS] = {NULL};#endif/* * Calendar time to Julian date conversions. * Julian date is commonly used in astronomical applications, * since it is numerically accurate and computationally simple. * The algorithms here will accurately convert between Julian day * and calendar date for all non-negative Julian days * (i.e. from Nov 23, -4713 on). * * Ref: Explanatory Supplement to the Astronomical Almanac, 1992. * University Science Books, 20 Edgehill Rd. Mill Valley CA 94941. * * Use the algorithm by Henry Fliegel, a former NASA/JPL colleague * now at Aerospace Corp. (hi, Henry!) * * These routines will be used by other date/time packages - tgl 97/02/25 */int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -