1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * datetime.h |
4 | * Definitions for date/time support code. |
5 | * The support code is shared with other date data types, |
6 | * including date, and time. |
7 | * |
8 | * |
9 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
10 | * Portions Copyright (c) 1994, Regents of the University of California |
11 | * |
12 | * src/include/utils/datetime.h |
13 | * |
14 | *------------------------------------------------------------------------- |
15 | */ |
16 | #ifndef DATETIME_H |
17 | #define DATETIME_H |
18 | |
19 | #include "nodes/nodes.h" |
20 | #include "utils/timestamp.h" |
21 | |
22 | /* this struct is declared in utils/tzparser.h: */ |
23 | struct tzEntry; |
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 alternative 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 | * Field types 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. Since those bits |
88 | * are stored in typmods, you can't change them without initdb! |
89 | */ |
90 | |
91 | #define RESERV 0 |
92 | #define MONTH 1 |
93 | #define YEAR 2 |
94 | #define DAY 3 |
95 | #define JULIAN 4 |
96 | #define TZ 5 /* fixed-offset timezone abbreviation */ |
97 | #define DTZ 6 /* fixed-offset timezone abbrev, DST */ |
98 | #define DYNTZ 7 /* dynamic timezone abbreviation */ |
99 | #define IGNORE_DTF 8 |
100 | #define AMPM 9 |
101 | #define HOUR 10 |
102 | #define MINUTE 11 |
103 | #define SECOND 12 |
104 | #define MILLISECOND 13 |
105 | #define MICROSECOND 14 |
106 | #define DOY 15 |
107 | #define DOW 16 |
108 | #define UNITS 17 |
109 | #define ADBC 18 |
110 | /* these are only for relative dates */ |
111 | #define AGO 19 |
112 | #define ABS_BEFORE 20 |
113 | #define ABS_AFTER 21 |
114 | /* generic fields to help with parsing */ |
115 | #define ISODATE 22 |
116 | #define ISOTIME 23 |
117 | /* these are only for parsing intervals */ |
118 | #define WEEK 24 |
119 | #define DECADE 25 |
120 | #define CENTURY 26 |
121 | #define MILLENNIUM 27 |
122 | /* hack for parsing two-word timezone specs "MET DST" etc */ |
123 | #define DTZMOD 28 /* "DST" as a separate word */ |
124 | /* reserved for unrecognized string values */ |
125 | #define UNKNOWN_FIELD 31 |
126 | |
127 | /* |
128 | * Token field definitions for time parsing and decoding. |
129 | * |
130 | * Some field type codes (see above) use these as the "value" in datetktbl[]. |
131 | * These are also used for bit masks in DecodeDateTime and friends |
132 | * so actually restrict them to within [0,31] for now. |
133 | * - thomas 97/06/19 |
134 | * Not all of these fields are used for masks in DecodeDateTime |
135 | * so allow some larger than 31. - thomas 1997-11-17 |
136 | * |
137 | * Caution: there are undocumented assumptions in the code that most of these |
138 | * values are not equal to IGNORE_DTF nor RESERV. Be very careful when |
139 | * renumbering values in either of these apparently-independent lists :-( |
140 | */ |
141 | |
142 | #define DTK_NUMBER 0 |
143 | #define DTK_STRING 1 |
144 | |
145 | #define DTK_DATE 2 |
146 | #define DTK_TIME 3 |
147 | #define DTK_TZ 4 |
148 | #define DTK_AGO 5 |
149 | |
150 | #define DTK_SPECIAL 6 |
151 | #define DTK_EARLY 9 |
152 | #define DTK_LATE 10 |
153 | #define DTK_EPOCH 11 |
154 | #define DTK_NOW 12 |
155 | #define DTK_YESTERDAY 13 |
156 | #define DTK_TODAY 14 |
157 | #define DTK_TOMORROW 15 |
158 | #define DTK_ZULU 16 |
159 | |
160 | #define DTK_DELTA 17 |
161 | #define DTK_SECOND 18 |
162 | #define DTK_MINUTE 19 |
163 | #define DTK_HOUR 20 |
164 | #define DTK_DAY 21 |
165 | #define DTK_WEEK 22 |
166 | #define DTK_MONTH 23 |
167 | #define DTK_QUARTER 24 |
168 | #define DTK_YEAR 25 |
169 | #define DTK_DECADE 26 |
170 | #define DTK_CENTURY 27 |
171 | #define DTK_MILLENNIUM 28 |
172 | #define DTK_MILLISEC 29 |
173 | #define DTK_MICROSEC 30 |
174 | #define DTK_JULIAN 31 |
175 | |
176 | #define DTK_DOW 32 |
177 | #define DTK_DOY 33 |
178 | #define DTK_TZ_HOUR 34 |
179 | #define DTK_TZ_MINUTE 35 |
180 | #define DTK_ISOYEAR 36 |
181 | #define DTK_ISODOW 37 |
182 | |
183 | |
184 | /* |
185 | * Bit mask definitions for time parsing. |
186 | */ |
187 | |
188 | #define DTK_M(t) (0x01 << (t)) |
189 | |
190 | /* Convenience: a second, plus any fractional component */ |
191 | #define DTK_ALL_SECS_M (DTK_M(SECOND) | DTK_M(MILLISECOND) | DTK_M(MICROSECOND)) |
192 | #define DTK_DATE_M (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY)) |
193 | #define DTK_TIME_M (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_ALL_SECS_M) |
194 | |
195 | /* |
196 | * Working buffer size for input and output of interval, timestamp, etc. |
197 | * Inputs that need more working space will be rejected early. Longer outputs |
198 | * will overrun buffers, so this must suffice for all possible output. As of |
199 | * this writing, interval_out() needs the most space at ~90 bytes. |
200 | */ |
201 | #define MAXDATELEN 128 |
202 | /* maximum possible number of fields in a date string */ |
203 | #define MAXDATEFIELDS 25 |
204 | /* only this many chars are stored in datetktbl */ |
205 | #define TOKMAXLEN 10 |
206 | |
207 | /* keep this struct small; it gets used a lot */ |
208 | typedef struct |
209 | { |
210 | char token[TOKMAXLEN + 1]; /* always NUL-terminated */ |
211 | char type; /* see field type codes above */ |
212 | int32 value; /* meaning depends on type */ |
213 | } datetkn; |
214 | |
215 | /* one of its uses is in tables of time zone abbreviations */ |
216 | typedef struct TimeZoneAbbrevTable |
217 | { |
218 | Size tblsize; /* size in bytes of TimeZoneAbbrevTable */ |
219 | int numabbrevs; /* number of entries in abbrevs[] array */ |
220 | datetkn abbrevs[FLEXIBLE_ARRAY_MEMBER]; |
221 | /* DynamicZoneAbbrev(s) may follow the abbrevs[] array */ |
222 | } TimeZoneAbbrevTable; |
223 | |
224 | /* auxiliary data for a dynamic time zone abbreviation (non-fixed-offset) */ |
225 | typedef struct DynamicZoneAbbrev |
226 | { |
227 | pg_tz *tz; /* NULL if not yet looked up */ |
228 | char zone[FLEXIBLE_ARRAY_MEMBER]; /* NUL-terminated zone name */ |
229 | } DynamicZoneAbbrev; |
230 | |
231 | |
232 | /* FMODULO() |
233 | * Macro to replace modf(), which is broken on some platforms. |
234 | * t = input and remainder |
235 | * q = integer part |
236 | * u = divisor |
237 | */ |
238 | #define FMODULO(t,q,u) \ |
239 | do { \ |
240 | (q) = (((t) < 0) ? ceil((t) / (u)) : floor((t) / (u))); \ |
241 | if ((q) != 0) (t) -= rint((q) * (u)); \ |
242 | } while(0) |
243 | |
244 | /* TMODULO() |
245 | * Like FMODULO(), but work on the timestamp datatype (now always int64). |
246 | * We assume that int64 follows the C99 semantics for division (negative |
247 | * quotients truncate towards zero). |
248 | */ |
249 | #define TMODULO(t,q,u) \ |
250 | do { \ |
251 | (q) = ((t) / (u)); \ |
252 | if ((q) != 0) (t) -= ((q) * (u)); \ |
253 | } while(0) |
254 | |
255 | /* |
256 | * Date/time validation |
257 | * Include check for leap year. |
258 | */ |
259 | |
260 | extern const char *const months[]; /* months (3-char abbreviations) */ |
261 | extern const char *const days[]; /* days (full names) */ |
262 | extern const int day_tab[2][13]; |
263 | |
264 | /* |
265 | * These are the rules for the Gregorian calendar, which was adopted in 1582. |
266 | * However, we use this calculation for all prior years as well because the |
267 | * SQL standard specifies use of the Gregorian calendar. This prevents the |
268 | * date 1500-02-29 from being stored, even though it is valid in the Julian |
269 | * calendar. |
270 | */ |
271 | #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) |
272 | |
273 | |
274 | /* |
275 | * Datetime input parsing routines (ParseDateTime, DecodeDateTime, etc) |
276 | * return zero or a positive value on success. On failure, they return |
277 | * one of these negative code values. DateTimeParseError may be used to |
278 | * produce a correct ereport. |
279 | */ |
280 | #define DTERR_BAD_FORMAT (-1) |
281 | #define DTERR_FIELD_OVERFLOW (-2) |
282 | #define DTERR_MD_FIELD_OVERFLOW (-3) /* triggers hint about DateStyle */ |
283 | #define DTERR_INTERVAL_OVERFLOW (-4) |
284 | #define DTERR_TZDISP_OVERFLOW (-5) |
285 | |
286 | |
287 | extern void GetCurrentDateTime(struct pg_tm *tm); |
288 | extern void GetCurrentTimeUsec(struct pg_tm *tm, fsec_t *fsec, int *tzp); |
289 | extern void j2date(int jd, int *year, int *month, int *day); |
290 | extern int date2j(int year, int month, int day); |
291 | |
292 | extern int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, |
293 | char **field, int *ftype, |
294 | int maxfields, int *numfields); |
295 | extern int DecodeDateTime(char **field, int *ftype, |
296 | int nf, int *dtype, |
297 | struct pg_tm *tm, fsec_t *fsec, int *tzp); |
298 | extern int DecodeTimezone(char *str, int *tzp); |
299 | extern int DecodeTimeOnly(char **field, int *ftype, |
300 | int nf, int *dtype, |
301 | struct pg_tm *tm, fsec_t *fsec, int *tzp); |
302 | extern int DecodeInterval(char **field, int *ftype, int nf, int range, |
303 | int *dtype, struct pg_tm *tm, fsec_t *fsec); |
304 | extern int DecodeISO8601Interval(char *str, |
305 | int *dtype, struct pg_tm *tm, fsec_t *fsec); |
306 | |
307 | extern void DateTimeParseError(int dterr, const char *str, |
308 | const char *datatype) pg_attribute_noreturn(); |
309 | |
310 | extern int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp); |
311 | extern int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp); |
312 | extern int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, |
313 | pg_tz *tzp, int *isdst); |
314 | |
315 | extern void EncodeDateOnly(struct pg_tm *tm, int style, char *str); |
316 | extern void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str); |
317 | extern void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str); |
318 | extern void EncodeInterval(struct pg_tm *tm, fsec_t fsec, int style, char *str); |
319 | extern void EncodeSpecialTimestamp(Timestamp dt, char *str); |
320 | |
321 | extern int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, |
322 | struct pg_tm *tm); |
323 | |
324 | extern int DecodeTimezoneAbbrev(int field, char *lowtoken, |
325 | int *offset, pg_tz **tz); |
326 | extern int DecodeSpecial(int field, char *lowtoken, int *val); |
327 | extern int DecodeUnits(int field, char *lowtoken, int *val); |
328 | |
329 | extern int j2day(int jd); |
330 | |
331 | extern Node *TemporalSimplify(int32 max_precis, Node *node); |
332 | |
333 | extern bool CheckDateTokenTables(void); |
334 | |
335 | extern TimeZoneAbbrevTable *ConvertTimeZoneAbbrevs(struct tzEntry *abbrevs, |
336 | int n); |
337 | extern void InstallTimeZoneAbbrevs(TimeZoneAbbrevTable *tbl); |
338 | |
339 | #endif /* DATETIME_H */ |
340 | |