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: */
23struct 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 */
208typedef 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 */
216typedef 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) */
225typedef 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) \
239do { \
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) \
250do { \
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
260extern const char *const months[]; /* months (3-char abbreviations) */
261extern const char *const days[]; /* days (full names) */
262extern 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
287extern void GetCurrentDateTime(struct pg_tm *tm);
288extern void GetCurrentTimeUsec(struct pg_tm *tm, fsec_t *fsec, int *tzp);
289extern void j2date(int jd, int *year, int *month, int *day);
290extern int date2j(int year, int month, int day);
291
292extern int ParseDateTime(const char *timestr, char *workbuf, size_t buflen,
293 char **field, int *ftype,
294 int maxfields, int *numfields);
295extern int DecodeDateTime(char **field, int *ftype,
296 int nf, int *dtype,
297 struct pg_tm *tm, fsec_t *fsec, int *tzp);
298extern int DecodeTimezone(char *str, int *tzp);
299extern int DecodeTimeOnly(char **field, int *ftype,
300 int nf, int *dtype,
301 struct pg_tm *tm, fsec_t *fsec, int *tzp);
302extern int DecodeInterval(char **field, int *ftype, int nf, int range,
303 int *dtype, struct pg_tm *tm, fsec_t *fsec);
304extern int DecodeISO8601Interval(char *str,
305 int *dtype, struct pg_tm *tm, fsec_t *fsec);
306
307extern void DateTimeParseError(int dterr, const char *str,
308 const char *datatype) pg_attribute_noreturn();
309
310extern int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp);
311extern int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp);
312extern int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr,
313 pg_tz *tzp, int *isdst);
314
315extern void EncodeDateOnly(struct pg_tm *tm, int style, char *str);
316extern void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str);
317extern void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str);
318extern void EncodeInterval(struct pg_tm *tm, fsec_t fsec, int style, char *str);
319extern void EncodeSpecialTimestamp(Timestamp dt, char *str);
320
321extern int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc,
322 struct pg_tm *tm);
323
324extern int DecodeTimezoneAbbrev(int field, char *lowtoken,
325 int *offset, pg_tz **tz);
326extern int DecodeSpecial(int field, char *lowtoken, int *val);
327extern int DecodeUnits(int field, char *lowtoken, int *val);
328
329extern int j2day(int jd);
330
331extern Node *TemporalSimplify(int32 max_precis, Node *node);
332
333extern bool CheckDateTokenTables(void);
334
335extern TimeZoneAbbrevTable *ConvertTimeZoneAbbrevs(struct tzEntry *abbrevs,
336 int n);
337extern void InstallTimeZoneAbbrevs(TimeZoneAbbrevTable *tbl);
338
339#endif /* DATETIME_H */
340