Header And Logo

PostgreSQL
| The world's most advanced open source database.

datetime.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * datetime.h
00004  *    Definitions for date/time support code.
00005  *    The support code is shared with other date data types,
00006  *     including abstime, reltime, date, and time.
00007  *
00008  *
00009  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00010  * Portions Copyright (c) 1994, Regents of the University of California
00011  *
00012  * src/include/utils/datetime.h
00013  *
00014  *-------------------------------------------------------------------------
00015  */
00016 #ifndef DATETIME_H
00017 #define DATETIME_H
00018 
00019 #include "nodes/nodes.h"
00020 #include "utils/timestamp.h"
00021 
00022 /* this struct is declared in utils/tzparser.h: */
00023 struct tzEntry;
00024 
00025 
00026 /* ----------------------------------------------------------------
00027  *              time types + support macros
00028  *
00029  * String definitions for standard time quantities.
00030  *
00031  * These strings are the defaults used to form output time strings.
00032  * Other alternative forms are hardcoded into token tables in datetime.c.
00033  * ----------------------------------------------------------------
00034  */
00035 
00036 #define DAGO            "ago"
00037 #define DCURRENT        "current"
00038 #define EPOCH           "epoch"
00039 #define INVALID         "invalid"
00040 #define EARLY           "-infinity"
00041 #define LATE            "infinity"
00042 #define NOW             "now"
00043 #define TODAY           "today"
00044 #define TOMORROW        "tomorrow"
00045 #define YESTERDAY       "yesterday"
00046 #define ZULU            "zulu"
00047 
00048 #define DMICROSEC       "usecond"
00049 #define DMILLISEC       "msecond"
00050 #define DSECOND         "second"
00051 #define DMINUTE         "minute"
00052 #define DHOUR           "hour"
00053 #define DDAY            "day"
00054 #define DWEEK           "week"
00055 #define DMONTH          "month"
00056 #define DQUARTER        "quarter"
00057 #define DYEAR           "year"
00058 #define DDECADE         "decade"
00059 #define DCENTURY        "century"
00060 #define DMILLENNIUM     "millennium"
00061 #define DA_D            "ad"
00062 #define DB_C            "bc"
00063 #define DTIMEZONE       "timezone"
00064 
00065 /*
00066  * Fundamental time field definitions for parsing.
00067  *
00068  *  Meridian:  am, pm, or 24-hour style.
00069  *  Millennium: ad, bc
00070  */
00071 
00072 #define AM      0
00073 #define PM      1
00074 #define HR24    2
00075 
00076 #define AD      0
00077 #define BC      1
00078 
00079 /*
00080  * Fields for time decoding.
00081  *
00082  * Can't have more of these than there are bits in an unsigned int
00083  * since these are turned into bit masks during parsing and decoding.
00084  *
00085  * Furthermore, the values for YEAR, MONTH, DAY, HOUR, MINUTE, SECOND
00086  * must be in the range 0..14 so that the associated bitmasks can fit
00087  * into the left half of an INTERVAL's typmod value.  Since those bits
00088  * are stored in typmods, you can't change them without initdb!
00089  */
00090 
00091 #define RESERV  0
00092 #define MONTH   1
00093 #define YEAR    2
00094 #define DAY     3
00095 #define JULIAN  4
00096 #define TZ      5
00097 #define DTZ     6
00098 #define DTZMOD  7
00099 #define IGNORE_DTF  8
00100 #define AMPM    9
00101 #define HOUR    10
00102 #define MINUTE  11
00103 #define SECOND  12
00104 #define MILLISECOND 13
00105 #define MICROSECOND 14
00106 #define DOY     15
00107 #define DOW     16
00108 #define UNITS   17
00109 #define ADBC    18
00110 /* these are only for relative dates */
00111 #define AGO     19
00112 #define ABS_BEFORE      20
00113 #define ABS_AFTER       21
00114 /* generic fields to help with parsing */
00115 #define ISODATE 22
00116 #define ISOTIME 23
00117 /* these are only for parsing intervals */
00118 #define WEEK        24
00119 #define DECADE      25
00120 #define CENTURY     26
00121 #define MILLENNIUM  27
00122 /* reserved for unrecognized string values */
00123 #define UNKNOWN_FIELD   31
00124 
00125 /*
00126  * Token field definitions for time parsing and decoding.
00127  * These need to fit into the datetkn table type.
00128  * At the moment, that means keep them within [-127,127].
00129  * These are also used for bit masks in DecodeDateDelta()
00130  *  so actually restrict them to within [0,31] for now.
00131  * - thomas 97/06/19
00132  * Not all of these fields are used for masks in DecodeDateDelta
00133  *  so allow some larger than 31. - thomas 1997-11-17
00134  */
00135 
00136 #define DTK_NUMBER      0
00137 #define DTK_STRING      1
00138 
00139 #define DTK_DATE        2
00140 #define DTK_TIME        3
00141 #define DTK_TZ          4
00142 #define DTK_AGO         5
00143 
00144 #define DTK_SPECIAL     6
00145 #define DTK_INVALID     7
00146 #define DTK_CURRENT     8
00147 #define DTK_EARLY       9
00148 #define DTK_LATE        10
00149 #define DTK_EPOCH       11
00150 #define DTK_NOW         12
00151 #define DTK_YESTERDAY   13
00152 #define DTK_TODAY       14
00153 #define DTK_TOMORROW    15
00154 #define DTK_ZULU        16
00155 
00156 #define DTK_DELTA       17
00157 #define DTK_SECOND      18
00158 #define DTK_MINUTE      19
00159 #define DTK_HOUR        20
00160 #define DTK_DAY         21
00161 #define DTK_WEEK        22
00162 #define DTK_MONTH       23
00163 #define DTK_QUARTER     24
00164 #define DTK_YEAR        25
00165 #define DTK_DECADE      26
00166 #define DTK_CENTURY     27
00167 #define DTK_MILLENNIUM  28
00168 #define DTK_MILLISEC    29
00169 #define DTK_MICROSEC    30
00170 #define DTK_JULIAN      31
00171 
00172 #define DTK_DOW         32
00173 #define DTK_DOY         33
00174 #define DTK_TZ_HOUR     34
00175 #define DTK_TZ_MINUTE   35
00176 #define DTK_ISOYEAR     36
00177 #define DTK_ISODOW      37
00178 
00179 
00180 /*
00181  * Bit mask definitions for time parsing.
00182  */
00183 
00184 #define DTK_M(t)        (0x01 << (t))
00185 
00186 /* Convenience: a second, plus any fractional component */
00187 #define DTK_ALL_SECS_M  (DTK_M(SECOND) | DTK_M(MILLISECOND) | DTK_M(MICROSECOND))
00188 #define DTK_DATE_M      (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
00189 #define DTK_TIME_M      (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_ALL_SECS_M)
00190 
00191 #define MAXDATELEN      63      /* maximum possible length of an input date
00192                                  * string (not counting tr. null) */
00193 #define MAXDATEFIELDS   25      /* maximum possible number of fields in a date
00194                                  * string */
00195 #define TOKMAXLEN       10      /* only this many chars are stored in
00196                                  * datetktbl */
00197 
00198 /* keep this struct small; it gets used a lot */
00199 typedef struct
00200 {
00201     char        token[TOKMAXLEN];
00202     char        type;
00203     char        value;          /* this may be unsigned, alas */
00204 } datetkn;
00205 
00206 /* one of its uses is in tables of time zone abbreviations */
00207 typedef struct TimeZoneAbbrevTable
00208 {
00209     int         numabbrevs;
00210     datetkn     abbrevs[1];     /* VARIABLE LENGTH ARRAY */
00211 } TimeZoneAbbrevTable;
00212 
00213 
00214 /* FMODULO()
00215  * Macro to replace modf(), which is broken on some platforms.
00216  * t = input and remainder
00217  * q = integer part
00218  * u = divisor
00219  */
00220 #define FMODULO(t,q,u) \
00221 do { \
00222     (q) = (((t) < 0) ? ceil((t) / (u)) : floor((t) / (u))); \
00223     if ((q) != 0) (t) -= rint((q) * (u)); \
00224 } while(0)
00225 
00226 /* TMODULO()
00227  * Like FMODULO(), but work on the timestamp datatype (either int64 or float8).
00228  * We assume that int64 follows the C99 semantics for division (negative
00229  * quotients truncate towards zero).
00230  */
00231 #ifdef HAVE_INT64_TIMESTAMP
00232 #define TMODULO(t,q,u) \
00233 do { \
00234     (q) = ((t) / (u)); \
00235     if ((q) != 0) (t) -= ((q) * (u)); \
00236 } while(0)
00237 #else
00238 #define TMODULO(t,q,u) \
00239 do { \
00240     (q) = (((t) < 0) ? ceil((t) / (u)) : floor((t) / (u))); \
00241     if ((q) != 0) (t) -= rint((q) * (u)); \
00242 } while(0)
00243 #endif
00244 
00245 /*
00246  * Date/time validation
00247  * Include check for leap year.
00248  */
00249 
00250 extern const int day_tab[2][13];
00251 
00252 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
00253 
00254 
00255 /*
00256  * Datetime input parsing routines (ParseDateTime, DecodeDateTime, etc)
00257  * return zero or a positive value on success.  On failure, they return
00258  * one of these negative code values.  DateTimeParseError may be used to
00259  * produce a correct ereport.
00260  */
00261 #define DTERR_BAD_FORMAT        (-1)
00262 #define DTERR_FIELD_OVERFLOW    (-2)
00263 #define DTERR_MD_FIELD_OVERFLOW (-3)    /* triggers hint about DateStyle */
00264 #define DTERR_INTERVAL_OVERFLOW (-4)
00265 #define DTERR_TZDISP_OVERFLOW   (-5)
00266 
00267 
00268 extern void GetCurrentDateTime(struct pg_tm * tm);
00269 extern void GetCurrentTimeUsec(struct pg_tm * tm, fsec_t *fsec, int *tzp);
00270 extern void j2date(int jd, int *year, int *month, int *day);
00271 extern int  date2j(int year, int month, int day);
00272 
00273 extern int ParseDateTime(const char *timestr, char *workbuf, size_t buflen,
00274               char **field, int *ftype,
00275               int maxfields, int *numfields);
00276 extern int DecodeDateTime(char **field, int *ftype,
00277                int nf, int *dtype,
00278                struct pg_tm * tm, fsec_t *fsec, int *tzp);
00279 extern int DecodeTimeOnly(char **field, int *ftype,
00280                int nf, int *dtype,
00281                struct pg_tm * tm, fsec_t *fsec, int *tzp);
00282 extern int DecodeInterval(char **field, int *ftype, int nf, int range,
00283                int *dtype, struct pg_tm * tm, fsec_t *fsec);
00284 extern int DecodeISO8601Interval(char *str,
00285                       int *dtype, struct pg_tm * tm, fsec_t *fsec);
00286 
00287 extern void DateTimeParseError(int dterr, const char *str,
00288                    const char *datatype) __attribute__((noreturn));
00289 
00290 extern int  DetermineTimeZoneOffset(struct pg_tm * tm, pg_tz *tzp);
00291 
00292 extern void EncodeDateOnly(struct pg_tm * tm, int style, char *str);
00293 extern void EncodeTimeOnly(struct pg_tm * tm, fsec_t fsec, bool print_tz, int tz, int style, char *str);
00294 extern void EncodeDateTime(struct pg_tm * tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str);
00295 extern void EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str);
00296 
00297 extern int  DecodeSpecial(int field, char *lowtoken, int *val);
00298 extern int  DecodeUnits(int field, char *lowtoken, int *val);
00299 
00300 extern int  j2day(int jd);
00301 
00302 extern Node *TemporalTransform(int32 max_precis, Node *node);
00303 
00304 extern bool CheckDateTokenTables(void);
00305 
00306 extern void ConvertTimeZoneAbbrevs(TimeZoneAbbrevTable *tbl,
00307                        struct tzEntry *abbrevs, int n);
00308 extern void InstallTimeZoneAbbrevs(TimeZoneAbbrevTable *tbl);
00309 
00310 extern Datum pg_timezone_abbrevs(PG_FUNCTION_ARGS);
00311 extern Datum pg_timezone_names(PG_FUNCTION_ARGS);
00312 
00313 #endif   /* DATETIME_H */