]> granicus.if.org Git - postgresql/blob - src/include/utils/datetime.h
56f018b6ccc5cf93558239f10b15d1164adc0eb5
[postgresql] / src / include / utils / datetime.h
1 /*-------------------------------------------------------------------------
2  *
3  * datetime.h
4  *        Definitions for the date/time and other date/time support code.
5  *        The support code is shared with other date data types,
6  *         including abstime, reltime, date, and time.
7  *
8  *
9  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
10  * Portions Copyright (c) 1994, Regents of the University of California
11  *
12  * $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.61 2006/09/16 20:14:33 tgl Exp $
13  *
14  *-------------------------------------------------------------------------
15  */
16 #ifndef DATETIME_H
17 #define DATETIME_H
18
19 #include <limits.h>
20 #include <math.h>
21
22 #include "utils/timestamp.h"
23 #include "utils/tzparser.h"
24
25
26 /* ----------------------------------------------------------------
27  *                              time types + support macros
28  *
29  * String definitions for standard time quantities.
30  *
31  * These strings are the defaults used to form output time strings.
32  * Other alternate forms are hardcoded into token tables in datetime.c.
33  * ----------------------------------------------------------------
34  */
35
36 #define DAGO                    "ago"
37 #define DCURRENT                "current"
38 #define EPOCH                   "epoch"
39 #define INVALID                 "invalid"
40 #define EARLY                   "-infinity"
41 #define LATE                    "infinity"
42 #define NOW                             "now"
43 #define TODAY                   "today"
44 #define TOMORROW                "tomorrow"
45 #define YESTERDAY               "yesterday"
46 #define ZULU                    "zulu"
47
48 #define DMICROSEC               "usecond"
49 #define DMILLISEC               "msecond"
50 #define DSECOND                 "second"
51 #define DMINUTE                 "minute"
52 #define DHOUR                   "hour"
53 #define DDAY                    "day"
54 #define DWEEK                   "week"
55 #define DMONTH                  "month"
56 #define DQUARTER                "quarter"
57 #define DYEAR                   "year"
58 #define DDECADE                 "decade"
59 #define DCENTURY                "century"
60 #define DMILLENNIUM             "millennium"
61 #define DA_D                    "ad"
62 #define DB_C                    "bc"
63 #define DTIMEZONE               "timezone"
64
65 /*
66  * Fundamental time field definitions for parsing.
67  *
68  *      Meridian:  am, pm, or 24-hour style.
69  *      Millennium: ad, bc
70  */
71
72 #define AM              0
73 #define PM              1
74 #define HR24    2
75
76 #define AD              0
77 #define BC              1
78
79 /*
80  * Fields for time decoding.
81  *
82  * Can't have more of these than there are bits in an unsigned int
83  * since these are turned into bit masks during parsing and decoding.
84  *
85  * Furthermore, the values for YEAR, MONTH, DAY, HOUR, MINUTE, SECOND
86  * must be in the range 0..14 so that the associated bitmasks can fit
87  * into the left half of an INTERVAL's typmod value.
88  */
89
90 #define RESERV  0
91 #define MONTH   1
92 #define YEAR    2
93 #define DAY             3
94 #define JULIAN  4
95 #define TZ              5
96 #define DTZ             6
97 #define DTZMOD  7
98 #define IGNORE_DTF      8
99 #define AMPM    9
100 #define HOUR    10
101 #define MINUTE  11
102 #define SECOND  12
103 #define DOY             13
104 #define DOW             14
105 #define UNITS   15
106 #define ADBC    16
107 /* these are only for relative dates */
108 #define AGO             17
109 #define ABS_BEFORE              18
110 #define ABS_AFTER               19
111 /* generic fields to help with parsing */
112 #define ISODATE 20
113 #define ISOTIME 21
114 /* reserved for unrecognized string values */
115 #define UNKNOWN_FIELD   31
116
117 /*
118  * Token field definitions for time parsing and decoding.
119  * These need to fit into the datetkn table type.
120  * At the moment, that means keep them within [-127,127].
121  * These are also used for bit masks in DecodeDateDelta()
122  *      so actually restrict them to within [0,31] for now.
123  * - thomas 97/06/19
124  * Not all of these fields are used for masks in DecodeDateDelta
125  *      so allow some larger than 31. - thomas 1997-11-17
126  */
127
128 #define DTK_NUMBER              0
129 #define DTK_STRING              1
130
131 #define DTK_DATE                2
132 #define DTK_TIME                3
133 #define DTK_TZ                  4
134 #define DTK_AGO                 5
135
136 #define DTK_SPECIAL             6
137 #define DTK_INVALID             7
138 #define DTK_CURRENT             8
139 #define DTK_EARLY               9
140 #define DTK_LATE                10
141 #define DTK_EPOCH               11
142 #define DTK_NOW                 12
143 #define DTK_YESTERDAY   13
144 #define DTK_TODAY               14
145 #define DTK_TOMORROW    15
146 #define DTK_ZULU                16
147
148 #define DTK_DELTA               17
149 #define DTK_SECOND              18
150 #define DTK_MINUTE              19
151 #define DTK_HOUR                20
152 #define DTK_DAY                 21
153 #define DTK_WEEK                22
154 #define DTK_MONTH               23
155 #define DTK_QUARTER             24
156 #define DTK_YEAR                25
157 #define DTK_DECADE              26
158 #define DTK_CENTURY             27
159 #define DTK_MILLENNIUM  28
160 #define DTK_MILLISEC    29
161 #define DTK_MICROSEC    30
162 #define DTK_JULIAN              31
163
164 #define DTK_DOW                 32
165 #define DTK_DOY                 33
166 #define DTK_TZ_HOUR             34
167 #define DTK_TZ_MINUTE   35
168
169
170 /*
171  * Bit mask definitions for time parsing.
172  */
173
174 #define DTK_M(t)                (0x01 << (t))
175
176 #define DTK_DATE_M              (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
177 #define DTK_TIME_M              (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_M(SECOND))
178
179 #define MAXDATELEN              51              /* maximum possible length of an input date
180                                                                  * string (not counting tr. null) */
181 #define MAXDATEFIELDS   25              /* maximum possible number of fields in a date
182                                                                  * string */
183 #define TOKMAXLEN               10              /* only this many chars are stored in
184                                                                  * datetktbl */
185
186 /* keep this struct small; it gets used a lot */
187 typedef struct
188 {
189         char            token[TOKMAXLEN];
190         char            type;
191         char            value;                  /* this may be unsigned, alas */
192 } datetkn;
193
194
195 /* FMODULO()
196  * Macro to replace modf(), which is broken on some platforms.
197  * t = input and remainder
198  * q = integer part
199  * u = divisor
200  */
201 #define FMODULO(t,q,u) \
202 do { \
203         (q) = (((t) < 0) ? ceil((t) / (u)) : floor((t) / (u))); \
204         if ((q) != 0) (t) -= rint((q) * (u)); \
205 } while(0)
206
207 /* TMODULO()
208  * Like FMODULO(), but work on the timestamp datatype (either int64 or float8).
209  * We assume that int64 follows the C99 semantics for division (negative
210  * quotients truncate towards zero).
211  */
212 #ifdef HAVE_INT64_TIMESTAMP
213 #define TMODULO(t,q,u) \
214 do { \
215         (q) = ((t) / (u)); \
216         if ((q) != 0) (t) -= ((q) * (u)); \
217 } while(0)
218 #else
219 #define TMODULO(t,q,u) \
220 do { \
221         (q) = (((t) < 0) ? ceil((t) / (u)) : floor((t) / (u))); \
222         if ((q) != 0) (t) -= rint((q) * (u)); \
223 } while(0)
224 #endif
225
226 /*
227  * Date/time validation
228  * Include check for leap year.
229  */
230
231 extern const int day_tab[2][13];
232
233 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
234
235
236 /* Julian date support for date2j() and j2date()
237  *
238  * IS_VALID_JULIAN checks the minimum date exactly, but is a bit sloppy
239  * about the maximum, since it's far enough out to not be especially
240  * interesting.
241  */
242
243 #define JULIAN_MINYEAR (-4713)
244 #define JULIAN_MINMONTH (11)
245 #define JULIAN_MINDAY (24)
246 #define JULIAN_MAXYEAR (5874898)
247
248 #define IS_VALID_JULIAN(y,m,d) ((((y) > JULIAN_MINYEAR) \
249   || (((y) == JULIAN_MINYEAR) && (((m) > JULIAN_MINMONTH) \
250   || (((m) == JULIAN_MINMONTH) && ((d) >= JULIAN_MINDAY))))) \
251  && ((y) < JULIAN_MAXYEAR))
252
253 /* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */
254 #define UNIX_EPOCH_JDATE                2440588 /* == date2j(1970, 1, 1) */
255 #define POSTGRES_EPOCH_JDATE    2451545 /* == date2j(2000, 1, 1) */
256
257
258 /*
259  * Datetime input parsing routines (ParseDateTime, DecodeDateTime, etc)
260  * return zero or a positive value on success.  On failure, they return
261  * one of these negative code values.  DateTimeParseError may be used to
262  * produce a correct ereport.
263  */
264 #define DTERR_BAD_FORMAT                (-1)
265 #define DTERR_FIELD_OVERFLOW    (-2)
266 #define DTERR_MD_FIELD_OVERFLOW (-3)    /* triggers hint about DateStyle */
267 #define DTERR_INTERVAL_OVERFLOW (-4)
268 #define DTERR_TZDISP_OVERFLOW   (-5)
269
270
271 extern void GetCurrentDateTime(struct pg_tm * tm);
272 extern void GetCurrentTimeUsec(struct pg_tm * tm, fsec_t *fsec, int *tzp);
273 extern void j2date(int jd, int *year, int *month, int *day);
274 extern int      date2j(int year, int month, int day);
275
276 extern int ParseDateTime(const char *timestr, char *workbuf, size_t buflen,
277                           char **field, int *ftype,
278                           int maxfields, int *numfields);
279 extern int DecodeDateTime(char **field, int *ftype,
280                            int nf, int *dtype,
281                            struct pg_tm * tm, fsec_t *fsec, int *tzp);
282 extern int DecodeTimeOnly(char **field, int *ftype,
283                            int nf, int *dtype,
284                            struct pg_tm * tm, fsec_t *fsec, int *tzp);
285 extern int DecodeInterval(char **field, int *ftype,
286                            int nf, int *dtype,
287                            struct pg_tm * tm, fsec_t *fsec);
288 extern void DateTimeParseError(int dterr, const char *str,
289                                    const char *datatype);
290
291 extern int      DetermineTimeZoneOffset(struct pg_tm * tm, pg_tz *tzp);
292
293 extern int      EncodeDateOnly(struct pg_tm * tm, int style, char *str);
294 extern int      EncodeTimeOnly(struct pg_tm * tm, fsec_t fsec, int *tzp, int style, char *str);
295 extern int      EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str);
296 extern int      EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str);
297
298 extern int      DecodeSpecial(int field, char *lowtoken, int *val);
299 extern int      DecodeUnits(int field, char *lowtoken, int *val);
300
301 extern int      j2day(int jd);
302
303 extern bool CheckDateTokenTables(void);
304 extern void InstallTimeZoneAbbrevs(tzEntry *abbrevs, int n);
305
306 extern Datum pg_timezone_abbrevs(PG_FUNCTION_ARGS);
307 extern Datum pg_timezone_names(PG_FUNCTION_ARGS);
308
309 #endif   /* DATETIME_H */