📄 nabstime.c
字号:
/* * nabstime.c * parse almost any absolute date getdate(3) can (& some it can't) * * Copyright (c) 1994, Regents of the University of California * * $Id: nabstime.c,v 1.55.2.1 1999/08/02 05:24:54 scrappy Exp $ * */#include <ctype.h>#include <sys/types.h>#include "postgres.h"#ifdef HAVE_FLOAT_H#include <float.h>#endif#ifdef HAVE_LIMITS_H#include <limits.h>#endif#ifndef USE_POSIX_TIME#include <sys/timeb.h>#endif#include "access/xact.h"#include "miscadmin.h"#include "utils/builtins.h"static AbsoluteTime tm2abstime(struct tm * tm, int tz);#define MIN_DAYNUM -24856 /* December 13, 1901 */#define MAX_DAYNUM 24854 /* January 18, 2038 *//* GetCurrentAbsoluteTime() * Get the current system time. Set timezone parameters if not specified elsewhere. * Define HasTZSet to allow clients to specify the default timezone. * * Returns the number of seconds since epoch (January 1 1970 GMT) */AbsoluteTimeGetCurrentAbsoluteTime(void){ time_t now;#ifdef USE_POSIX_TIME struct tm *tm; now = time(NULL);#else /* ! USE_POSIX_TIME */ struct timeb tb; /* the old V7-ism */ ftime(&tb); now = tb.time;#endif if (!HasCTZSet) {#ifdef USE_POSIX_TIME#if defined(HAVE_TM_ZONE) tm = localtime(&now); CTimeZone = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */ CDayLight = (tm->tm_isdst > 0);#ifdef NOT_USED /* * XXX is there a better way to get local timezone string w/o * tzname? - tgl 97/03/18 */ strftime(CTZName, MAXTZLEN, "%Z", tm);#endif /* * XXX FreeBSD man pages indicate that this should work - thomas * 1998-12-12 */ strcpy(CTZName, tm->tm_zone);#elif defined(HAVE_INT_TIMEZONE) tm = localtime(&now); CDayLight = tm->tm_isdst; CTimeZone =#ifdef __CYGWIN32__ (tm->tm_isdst ? (_timezone - 3600) : _timezone);#else (tm->tm_isdst ? (timezone - 3600) : timezone);#endif strcpy(CTZName, tzname[tm->tm_isdst]);#else#error USE_POSIX_TIME defined but no time zone available#endif#else /* ! USE_POSIX_TIME */ CTimeZone = tb.timezone * 60; CDayLight = (tb.dstflag != 0); /* * XXX does this work to get the local timezone string in V7? - * tgl 97/03/18 */ strftime(CTZName, MAXTZLEN, "%Z", localtime(&now));#endif };#ifdef DATEDEBUG printf("GetCurrentAbsoluteTime- timezone is %s -> %d seconds from UTC\n", CTZName, CTimeZone);#endif return (AbsoluteTime) now;} /* GetCurrentAbsoluteTime() */voidGetCurrentTime(struct tm * tm){ int tz; abstime2tm(GetCurrentTransactionStartTime(), &tz, tm, NULL); return;} /* GetCurrentTime() */voidabstime2tm(AbsoluteTime time, int *tzp, struct tm * tm, char *tzn){#ifdef USE_POSIX_TIME struct tm *tx;#else /* ! USE_POSIX_TIME */ struct timeb tb; /* the old V7-ism */ ftime(&tb);#endif#ifdef USE_POSIX_TIME if (tzp != NULL) tx = localtime((time_t *) &time); else { tx = gmtime((time_t *) &time); };#endif#if defined(DATEDEBUG)#if defined(HAVE_TM_ZONE) printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s dst=%d\n", tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec, tx->tm_zone, tx->tm_isdst);#elif defined(HAVE_INT_TIMEZONE) printf("datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02d %s %s dst=%d\n", tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, tx->tm_sec, tzname[0], tzname[1], tx->tm_isdst);#endif#endif#ifdef USE_POSIX_TIME tm->tm_year = tx->tm_year + 1900; tm->tm_mon = tx->tm_mon + 1; tm->tm_mday = tx->tm_mday; tm->tm_hour = tx->tm_hour; tm->tm_min = tx->tm_min; tm->tm_sec = tx->tm_sec; tm->tm_isdst = tx->tm_isdst;#if defined(HAVE_TM_ZONE) tm->tm_gmtoff = tx->tm_gmtoff; tm->tm_zone = tx->tm_zone; if (tzp != NULL) *tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */ /* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */ if (tzn != NULL) strcpy(tzn, tm->tm_zone);#elif defined(HAVE_INT_TIMEZONE) if (tzp != NULL)#ifdef __CYGWIN__ *tzp = (tm->tm_isdst ? (_timezone - 3600) : _timezone);#else *tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);#endif if (tzn != NULL) strcpy(tzn, tzname[tm->tm_isdst]);#else#error POSIX time support is broken#endif#else /* ! USE_POSIX_TIME */ if (tzp != NULL) *tzp = tb.timezone * 60; /* * XXX does this work to get the local timezone string in V7? - tgl * 97/03/18 */ if (tzn != NULL) strftime(tzn, MAXTZLEN, "%Z", localtime(&now));#endif return;} /* abstime2tm() *//* tm2abstime() * Convert a tm structure to abstime. * Note that tm has full year (not 1900-based) and 1-based month. */static AbsoluteTimetm2abstime(struct tm * tm, int tz){ int day, sec; /* validate, before going out of range on some members */ if (tm->tm_year < 1901 || tm->tm_year > 2038 || tm->tm_mon < 1 || tm->tm_mon > 12 || tm->tm_mday < 1 || tm->tm_mday > 31 || tm->tm_hour < 0 || tm->tm_hour >= 24 || tm->tm_min < 0 || tm->tm_min > 59 || tm->tm_sec < 0 || tm->tm_sec > 59) return INVALID_ABSTIME; day = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(1970, 1, 1)); /* check for time out of range */ if ((day < MIN_DAYNUM) || (day > MAX_DAYNUM)) return INVALID_ABSTIME; /* convert to seconds */ sec = tm->tm_sec + tz + (tm->tm_min + (day * 24 + tm->tm_hour) * 60) * 60; /* check for overflow */ if ((day == MAX_DAYNUM && sec < 0) || (day == MIN_DAYNUM && sec > 0)) return INVALID_ABSTIME; /* check for reserved values (e.g. "current" on edge of usual range */ if (!AbsoluteTimeIsReal(sec)) return INVALID_ABSTIME; return sec;} /* tm2abstime() *//* nabstimein() * Decode date/time string and return abstime. */AbsoluteTimenabstimein(char *str){ AbsoluteTime result; double fsec; int tz = 0; struct tm date, *tm = &date; char *field[MAXDATEFIELDS]; char lowstr[MAXDATELEN + 1]; int dtype; int nf, ftype[MAXDATEFIELDS]; if (!PointerIsValid(str)) elog(ERROR, "Bad (null) abstime external representation", NULL); if (strlen(str) > MAXDATELEN) elog(ERROR, "Bad (length) abstime external representation '%s'", str); if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0) || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0)) elog(ERROR, "Bad abstime external representation '%s'", str);#ifdef DATEDEBUG printf("nabstimein- %d fields are type %d (DTK_DATE=%d)\n", nf, dtype, DTK_DATE);#endif switch (dtype) { case DTK_DATE: result = tm2abstime(tm, tz); break; case DTK_EPOCH: result = EPOCH_ABSTIME; break; case DTK_CURRENT: result = CURRENT_ABSTIME; break; case DTK_LATE: result = NOEND_ABSTIME; break; case DTK_EARLY: result = NOSTART_ABSTIME; break; case DTK_INVALID: result = INVALID_ABSTIME; break; default: elog(ERROR, "Bad abstime (internal coding error) '%s'", str); result = INVALID_ABSTIME; break; }; return result;} /* nabstimein() *//* nabstimeout() * Given an AbsoluteTime return the English text version of the date */char *nabstimeout(AbsoluteTime time){ char *result; int tz; double fsec = 0; struct tm tt, *tm = &tt; char buf[MAXDATELEN + 1]; char zone[MAXDATELEN + 1], *tzn = zone; switch (time) { case EPOCH_ABSTIME: strcpy(buf, EPOCH); break; case INVALID_ABSTIME: strcpy(buf, INVALID); break; case CURRENT_ABSTIME: strcpy(buf, DCURRENT); break; case NOEND_ABSTIME: strcpy(buf, LATE); break; case NOSTART_ABSTIME: strcpy(buf, EARLY); break; default: abstime2tm(time, &tz, tm, tzn); EncodeDateTime(tm, fsec, &tz, &tzn, DateStyle, buf); break; } result = palloc(strlen(buf) + 1); strcpy(result, buf); return result;} /* nabstimeout() *//* * AbsoluteTimeIsBefore -- true iff time1 is before time2. * AbsoluteTimeIsBefore -- true iff time1 is after time2. */boolAbsoluteTimeIsBefore(AbsoluteTime time1, AbsoluteTime time2){ Assert(AbsoluteTimeIsValid(time1)); Assert(AbsoluteTimeIsValid(time2)); if (time1 == CURRENT_ABSTIME) time1 = GetCurrentTransactionStartTime(); if (time2 == CURRENT_ABSTIME) time2 = GetCurrentTransactionStartTime(); return time1 < time2;}#ifdef NOT_USEDboolAbsoluteTimeIsAfter(AbsoluteTime time1, AbsoluteTime time2){ Assert(AbsoluteTimeIsValid(time1)); Assert(AbsoluteTimeIsValid(time2)); if (time1 == CURRENT_ABSTIME) time1 = GetCurrentTransactionStartTime(); if (time2 == CURRENT_ABSTIME) time2 = GetCurrentTransactionStartTime(); return time1 > time2;}#endif/* abstime_finite() */boolabstime_finite(AbsoluteTime abstime){ return ((abstime != INVALID_ABSTIME) && (abstime != NOSTART_ABSTIME) && (abstime != NOEND_ABSTIME));} /* abstime_finite() *//* * abstimeeq - returns 1, iff arguments are equal * abstimene - returns 1, iff arguments are not equal * abstimelt - returns 1, iff t1 less than t2 * abstimegt - returns 1, iff t1 greater than t2 * abstimele - returns 1, iff t1 less than or equal to t2 * abstimege - returns 1, iff t1 greater than or equal to t2 */boolabstimeeq(AbsoluteTime t1, AbsoluteTime t2){ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME) return FALSE; if (t1 == CURRENT_ABSTIME) t1 = GetCurrentTransactionStartTime(); if (t2 == CURRENT_ABSTIME) t2 = GetCurrentTransactionStartTime(); return t1 == t2;}boolabstimene(AbsoluteTime t1, AbsoluteTime t2){ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME) return FALSE; if (t1 == CURRENT_ABSTIME) t1 = GetCurrentTransactionStartTime(); if (t2 == CURRENT_ABSTIME) t2 = GetCurrentTransactionStartTime(); return t1 != t2;}boolabstimelt(AbsoluteTime t1, AbsoluteTime t2){ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME) return FALSE; if (t1 == CURRENT_ABSTIME) t1 = GetCurrentTransactionStartTime(); if (t2 == CURRENT_ABSTIME) t2 = GetCurrentTransactionStartTime(); return t1 < t2;}boolabstimegt(AbsoluteTime t1, AbsoluteTime t2){ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME) return FALSE; if (t1 == CURRENT_ABSTIME) t1 = GetCurrentTransactionStartTime(); if (t2 == CURRENT_ABSTIME) t2 = GetCurrentTransactionStartTime(); return t1 > t2;}boolabstimele(AbsoluteTime t1, AbsoluteTime t2){ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME) return FALSE; if (t1 == CURRENT_ABSTIME) t1 = GetCurrentTransactionStartTime(); if (t2 == CURRENT_ABSTIME) t2 = GetCurrentTransactionStartTime(); return t1 <= t2;}boolabstimege(AbsoluteTime t1, AbsoluteTime t2){ if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME) return FALSE; if (t1 == CURRENT_ABSTIME) t1 = GetCurrentTransactionStartTime(); if (t2 == CURRENT_ABSTIME) t2 = GetCurrentTransactionStartTime(); return t1 >= t2;}/* datetime_abstime() * Convert datetime to abstime. */AbsoluteTimedatetime_abstime(DateTime *datetime){ AbsoluteTime result; double fsec; struct tm tt, *tm = &tt; if (!PointerIsValid(datetime)) { result = INVALID_ABSTIME; } else if (DATETIME_IS_INVALID(*datetime)) { result = INVALID_ABSTIME; } else if (DATETIME_IS_NOBEGIN(*datetime)) { result = NOSTART_ABSTIME; } else if (DATETIME_IS_NOEND(*datetime)) { result = NOEND_ABSTIME; } else { if (DATETIME_IS_RELATIVE(*datetime)) { datetime2tm(SetDateTime(*datetime), NULL, tm, &fsec, NULL); result = tm2abstime(tm, 0); } else if (datetime2tm(*datetime, NULL, tm, &fsec, NULL) == 0) { result = tm2abstime(tm, 0); } else { result = INVALID_ABSTIME; }; }; return result;} /* datetime_abstime() *//* abstime_datetime() * Convert abstime to datetime. */DateTime *abstime_datetime(AbsoluteTime abstime){ DateTime *result; if (!PointerIsValid(result = palloc(sizeof(DateTime)))) elog(ERROR, "Unable to allocate space to convert abstime to datetime", NULL); switch (abstime) { case INVALID_ABSTIME: DATETIME_INVALID(*result); break; case NOSTART_ABSTIME: DATETIME_NOBEGIN(*result); break; case NOEND_ABSTIME: DATETIME_NOEND(*result); break; case EPOCH_ABSTIME: DATETIME_EPOCH(*result); break; case CURRENT_ABSTIME: DATETIME_CURRENT(*result); break; default: *result = abstime + ((date2j(1970, 1, 1) - date2j(2000, 1, 1)) * 86400); break; }; return result;} /* abstime_datetime() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -