MobilityDB 1.1
datetime.h
Go to the documentation of this file.
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-2021, 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/* Definitions of the global variables taken from miscadmin.h */
26extern int DateStyle;
27extern int DateOrder;
28extern int IntervalStyle;
29
30/* valid DateOrder values taken */
31#define DATEORDER_YMD 0
32#define DATEORDER_DMY 1
33#define DATEORDER_MDY 2
34
35/* Defitinitions taken from dt.h */
36
37#define MAXTZLEN 10
38
39typedef int32 fsec_t;
40
41#define USE_POSTGRES_DATES 0
42#define USE_ISO_DATES 1
43#define USE_SQL_DATES 2
44#define USE_GERMAN_DATES 3
45#define USE_XSD_DATES 4
46
47#define INTSTYLE_POSTGRES 0
48#define INTSTYLE_POSTGRES_VERBOSE 1
49#define INTSTYLE_SQL_STANDARD 2
50#define INTSTYLE_ISO_8601 3
51
52#define INTERVAL_FULL_RANGE (0x7FFF)
53#define INTERVAL_MASK(b) (1 << (b))
54#define MAX_INTERVAL_PRECISION 6
55
56#define DTERR_BAD_FORMAT (-1)
57#define DTERR_FIELD_OVERFLOW (-2)
58#define DTERR_MD_FIELD_OVERFLOW (-3) /* triggers hint about DateStyle */
59#define DTERR_INTERVAL_OVERFLOW (-4)
60#define DTERR_TZDISP_OVERFLOW (-5)
61
62/* ----------------------------------------------------------------
63 * time types + support macros
64 *
65 * String definitions for standard time quantities.
66 *
67 * These strings are the defaults used to form output time strings.
68 * Other alternative forms are hardcoded into token tables in datetime.c.
69 * ----------------------------------------------------------------
70 */
71
72#define DAGO "ago"
73#define DCURRENT "current"
74#define EPOCH "epoch"
75#define INVALID "invalid"
76#define EARLY "-infinity"
77#define LATE "infinity"
78#define NOW "now"
79#define TODAY "today"
80#define TOMORROW "tomorrow"
81#define YESTERDAY "yesterday"
82#define ZULU "zulu"
83
84#define DMICROSEC "usecond"
85#define DMILLISEC "msecond"
86#define DSECOND "second"
87#define DMINUTE "minute"
88#define DHOUR "hour"
89#define DDAY "day"
90#define DWEEK "week"
91#define DMONTH "month"
92#define DQUARTER "quarter"
93#define DYEAR "year"
94#define DDECADE "decade"
95#define DCENTURY "century"
96#define DMILLENNIUM "millennium"
97#define DA_D "ad"
98#define DB_C "bc"
99#define DTIMEZONE "timezone"
100
101/*
102 * Fundamental time field definitions for parsing.
103 *
104 * Meridian: am, pm, or 24-hour style.
105 * Millennium: ad, bc
106 */
107
108#define AM 0
109#define PM 1
110#define HR24 2
111
112#define AD 0
113#define BC 1
114
115/*
116 * Field types for time decoding.
117 *
118 * Can't have more of these than there are bits in an unsigned int
119 * since these are turned into bit masks during parsing and decoding.
120 *
121 * Furthermore, the values for YEAR, MONTH, DAY, HOUR, MINUTE, SECOND
122 * must be in the range 0..14 so that the associated bitmasks can fit
123 * into the left half of an INTERVAL's typmod value. Since those bits
124 * are stored in typmods, you can't change them without initdb!
125 */
126
127#define RESERV 0
128#define MONTH 1
129#define YEAR 2
130#define DAY 3
131#define JULIAN 4
132#define TZ 5 /* fixed-offset timezone abbreviation */
133#define DTZ 6 /* fixed-offset timezone abbrev, DST */
134#define DYNTZ 7 /* dynamic timezone abbreviation */
135#define IGNORE_DTF 8
136#define AMPM 9
137#define HOUR 10
138#define MINUTE 11
139#define SECOND 12
140#define MILLISECOND 13
141#define MICROSECOND 14
142#define DOY 15
143#define DOW 16
144#define UNITS 17
145#define ADBC 18
146/* these are only for relative dates */
147#define AGO 19
148#define ABS_BEFORE 20
149#define ABS_AFTER 21
150/* generic fields to help with parsing */
151#define ISODATE 22
152#define ISOTIME 23
153/* these are only for parsing intervals */
154#define WEEK 24
155#define DECADE 25
156#define CENTURY 26
157#define MILLENNIUM 27
158/* hack for parsing two-word timezone specs "MET DST" etc */
159#define DTZMOD 28 /* "DST" as a separate word */
160/* reserved for unrecognized string values */
161#define UNKNOWN_FIELD 31
162
163/*
164 * Token field definitions for time parsing and decoding.
165 *
166 * Some field type codes (see above) use these as the "value" in datetktbl[].
167 * These are also used for bit masks in DecodeDateTime and friends
168 * so actually restrict them to within [0,31] for now.
169 * - thomas 97/06/19
170 * Not all of these fields are used for masks in DecodeDateTime
171 * so allow some larger than 31. - thomas 1997-11-17
172 *
173 * Caution: there are undocumented assumptions in the code that most of these
174 * values are not equal to IGNORE_DTF nor RESERV. Be very careful when
175 * renumbering values in either of these apparently-independent lists :-(
176 */
177
178#define DTK_NUMBER 0
179#define DTK_STRING 1
180
181#define DTK_DATE 2
182#define DTK_TIME 3
183#define DTK_TZ 4
184#define DTK_AGO 5
185
186#define DTK_SPECIAL 6
187#define DTK_EARLY 9
188#define DTK_LATE 10
189#define DTK_EPOCH 11
190#define DTK_NOW 12
191#define DTK_YESTERDAY 13
192#define DTK_TODAY 14
193#define DTK_TOMORROW 15
194#define DTK_ZULU 16
195
196#define DTK_DELTA 17
197#define DTK_SECOND 18
198#define DTK_MINUTE 19
199#define DTK_HOUR 20
200#define DTK_DAY 21
201#define DTK_WEEK 22
202#define DTK_MONTH 23
203#define DTK_QUARTER 24
204#define DTK_YEAR 25
205#define DTK_DECADE 26
206#define DTK_CENTURY 27
207#define DTK_MILLENNIUM 28
208#define DTK_MILLISEC 29
209#define DTK_MICROSEC 30
210#define DTK_JULIAN 31
211
212#define DTK_DOW 32
213#define DTK_DOY 33
214#define DTK_TZ_HOUR 34
215#define DTK_TZ_MINUTE 35
216#define DTK_ISOYEAR 36
217#define DTK_ISODOW 37
218
219
220/*
221 * Bit mask definitions for time parsing.
222 */
223
224#define DTK_M(t) (0x01 << (t))
225
226/* Convenience: a second, plus any fractional component */
227#define DTK_ALL_SECS_M (DTK_M(SECOND) | DTK_M(MILLISECOND) | DTK_M(MICROSECOND))
228#define DTK_DATE_M (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
229#define DTK_TIME_M (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_ALL_SECS_M)
230
231/*
232 * Working buffer size for input and output of interval, timestamp, etc.
233 * Inputs that need more working space will be rejected early. Longer outputs
234 * will overrun buffers, so this must suffice for all possible output. As of
235 * this writing, interval_out() needs the most space at ~90 bytes.
236 */
237#define MAXDATELEN 128
238/* maximum possible number of fields in a date string */
239#define MAXDATEFIELDS 25
240/* only this many chars are stored in datetktbl */
241#define TOKMAXLEN 10
242
243/* keep this struct small; it gets used a lot */
244typedef struct
245{
246 char token[TOKMAXLEN + 1]; /* always NUL-terminated */
247 char type; /* see field type codes above */
248 int32 value; /* meaning depends on type */
249} datetkn;
250
251/* one of its uses is in tables of time zone abbreviations */
253{
254 Size tblsize; /* size in bytes of TimeZoneAbbrevTable */
255 int numabbrevs; /* number of entries in abbrevs[] array */
257 /* DynamicZoneAbbrev(s) may follow the abbrevs[] array */
259
260/* auxiliary data for a dynamic time zone abbreviation (non-fixed-offset) */
261typedef struct DynamicZoneAbbrev
262{
263 pg_tz *tz; /* NULL if not yet looked up */
264 char zone[FLEXIBLE_ARRAY_MEMBER]; /* NUL-terminated zone name */
266
267
268/* FMODULO()
269 * Macro to replace modf(), which is broken on some platforms.
270 * t = input and remainder
271 * q = integer part
272 * u = divisor
273 */
274#define FMODULO(t,q,u) \
275do { \
276 (q) = (((t) < 0) ? ceil((t) / (u)) : floor((t) / (u))); \
277 if ((q) != 0) (t) -= rint((q) * (u)); \
278} while(0)
279
280/* TMODULO()
281 * Like FMODULO(), but work on the timestamp datatype (now always int64).
282 * We assume that int64 follows the C99 semantics for division (negative
283 * quotients truncate towards zero).
284 */
285#define TMODULO(t,q,u) \
286do { \
287 (q) = ((t) / (u)); \
288 if ((q) != 0) (t) -= ((q) * (u)); \
289} while(0)
290
291/*
292 * Date/time validation
293 * Include check for leap year.
294 */
295
296extern const char *const months[]; /* months (3-char abbreviations) */
297extern const char *const days[]; /* days (full names) */
298extern const int day_tab[2][13];
299
300/*
301 * These are the rules for the Gregorian calendar, which was adopted in 1582.
302 * However, we use this calculation for all prior years as well because the
303 * SQL standard specifies use of the Gregorian calendar. This prevents the
304 * date 1500-02-29 from being stored, even though it is valid in the Julian
305 * calendar.
306 */
307#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
308
309/*
310 * Datetime input parsing routines (ParseDateTime, DecodeDateTime, etc)
311 * return zero or a positive value on success. On failure, they return
312 * one of these negative code values. DateTimeParseError may be used to
313 * produce a correct ereport.
314 */
315#define DTERR_BAD_FORMAT (-1)
316#define DTERR_FIELD_OVERFLOW (-2)
317#define DTERR_MD_FIELD_OVERFLOW (-3) /* triggers hint about DateStyle */
318#define DTERR_INTERVAL_OVERFLOW (-4)
319#define DTERR_TZDISP_OVERFLOW (-5)
320
321extern void GetCurrentDateTime(struct pg_tm *tm);
322extern void GetCurrentTimeUsec(struct pg_tm *tm, fsec_t *fsec, int *tzp);
323extern void j2date(int jd, int *year, int *month, int *day);
324extern int date2j(int year, int month, int day);
325
326extern int ParseDateTime(const char *timestr, char *workbuf, size_t buflen,
327 char **field, int *ftype,
328 int maxfields, int *numfields);
329extern int DecodeDateTime(char **field, int *ftype,
330 int nf, int *dtype,
331 struct pg_tm *tm, fsec_t *fsec, int *tzp);
332extern int DecodeTimezone(char *str, int *tzp);
333extern int DecodeTimeOnly(char **field, int *ftype,
334 int nf, int *dtype,
335 struct pg_tm *tm, fsec_t *fsec, int *tzp);
336extern int DecodeInterval(char **field, int *ftype, int nf, int range,
337 int *dtype, struct pg_tm *tm, fsec_t *fsec);
338extern int DecodeISO8601Interval(char *str,
339 int *dtype, struct pg_tm *tm, fsec_t *fsec);
340
341extern void DateTimeParseError(int dterr, const char *str,
342 const char *datatype) pg_attribute_noreturn();
343
344extern int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp);
345extern int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp);
346extern int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr,
347 pg_tz *tzp, int *isdst);
348
349extern void EncodeDateOnly(struct pg_tm *tm, int style, char *str);
350extern void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str);
351extern void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str);
352extern void EncodeInterval(struct pg_tm *tm, fsec_t fsec, int style, char *str);
353extern void EncodeSpecialTimestamp(Timestamp dt, char *str);
354
355extern int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc,
356 struct pg_tm *tm);
357
358extern int DecodeTimezoneAbbrev(int field, char *lowtoken,
359 int *offset, pg_tz **tz);
360extern int DecodeSpecial(int field, char *lowtoken, int *val);
361extern int DecodeUnits(int field, char *lowtoken, int *val);
362
363extern int j2day(int jd);
364
365// MobilityDB
366// extern Node *TemporalSimplify(int32 max_precis, Node *node);
367
368extern bool CheckDateTokenTables(void);
369
370extern TimeZoneAbbrevTable *ConvertTimeZoneAbbrevs(struct tzEntry *abbrevs,
371 int n);
373
374extern void AdjustTimestampForTypmod(Timestamp *time, int32 typmod);
375extern bool AdjustTimestampForTypmodError(Timestamp *time, int32 typmod,
376 bool *error);
377
378#endif /* DATETIME_H */
#define pg_attribute_noreturn()
Definition: c.h:180
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:351
size_t Size
Definition: c.h:545
const int day_tab[2][13]
Definition: datetime.c:48
int DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: datetime.c:1707
int DecodeTimezoneAbbrev(int field, char *lowtoken, int *offset, pg_tz **tz)
Definition: datetime.c:2930
int32 fsec_t
Definition: datetime.h:39
int DecodeTimezone(char *str, int *tzp)
Definition: datetime.c:2853
int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, pg_tz *tzp, int *isdst)
int DateStyle
Definition: pg_types.c:88
void InstallTimeZoneAbbrevs(TimeZoneAbbrevTable *tbl)
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition: datetime.c:580
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
Definition: datetime.c:1471
void AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
Definition: pg_types.c:463
int DecodeSpecial(int field, char *lowtoken, int *val)
Definition: datetime.c:2984
void EncodeSpecialTimestamp(Timestamp dt, char *str)
Definition: timestamp.c:37
bool CheckDateTokenTables(void)
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: datetime.c:800
void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str)
Definition: datetime.c:3915
int j2day(int jd)
Definition: datetime.c:314
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition: datetime.c:2430
struct TimeZoneAbbrevTable TimeZoneAbbrevTable
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:282
void GetCurrentDateTime(struct pg_tm *tm)
Definition: datetime.c:335
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:3944
void EncodeInterval(struct pg_tm *tm, fsec_t fsec, int style, char *str)
Definition: datetime.c:4181
void DateTimeParseError(int dterr, const char *str, const char *datatype) pg_attribute_noreturn()
Definition: datetime.c:3707
int DecodeInterval(char **field, int *ftype, int nf, int range, int *dtype, struct pg_tm *tm, fsec_t *fsec)
Definition: datetime.c:3038
TimeZoneAbbrevTable * ConvertTimeZoneAbbrevs(struct tzEntry *abbrevs, int n)
int DecodeISO8601Interval(char *str, int *dtype, struct pg_tm *tm, fsec_t *fsec)
Definition: datetime.c:3462
const char *const months[]
Definition: datetime.c:54
bool AdjustTimestampForTypmodError(Timestamp *time, int32 typmod, bool *error)
Definition: pg_types.c:410
int DecodeUnits(int field, char *lowtoken, int *val)
Definition: datetime.c:3670
int IntervalStyle
Definition: pg_types.c:90
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:3831
struct DynamicZoneAbbrev DynamicZoneAbbrev
int date2j(int year, int month, int day)
Definition: datetime.c:257
void GetCurrentTimeUsec(struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: datetime.c:356
int DateOrder
Definition: pg_types.c:89
const char *const days[]
Definition: datetime.c:57
#define TOKMAXLEN
Definition: datetime.h:241
int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp)
Definition: datetime.c:1630
static struct pg_tm tm
Definition: localtime.c:104
INSERT INTO trips SELECT day
Definition: meos_disassemble_berlinmod.txt:22
int64 Timestamp
Definition: pg_ext_defs.in.h:18
int64 TimestampTz
Definition: pg_ext_defs.in.h:19
int32 fsec_t
Definition: pg_ext_defs.in.h:21
signed int int32
Definition: pg_ext_defs.in.h:8
char zone[FLEXIBLE_ARRAY_MEMBER]
Definition: datetime.h:264
pg_tz * tz
Definition: datetime.h:263
Definition: datetime.h:262
int numabbrevs
Definition: datetime.h:255
Size tblsize
Definition: datetime.h:254
datetkn abbrevs[FLEXIBLE_ARRAY_MEMBER]
Definition: datetime.h:256
Definition: datetime.h:253
int32 value
Definition: datetime.h:248
char type
Definition: datetime.h:247
Definition: datetime.h:245
Definition: pgtime.h:26
Definition: pgtz.h:66