6
#include <pgtypes_timestamp.h>
10
#ifdef HAVE_INT64_TIMESTAMP
15
typedef double fsec_t;
17
/* round off to MAX_TIMESTAMP_PRECISION decimal places */
18
/* note: this is also used for rounding off intervals */
19
#define TS_PREC_INV 1000000.0
20
#define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV)
23
#define USE_POSTGRES_DATES 0
24
#define USE_ISO_DATES 1
25
#define USE_SQL_DATES 2
26
#define USE_GERMAN_DATES 3
28
#define INTSTYLE_POSTGRES 0
29
#define INTSTYLE_POSTGRES_VERBOSE 1
30
#define INTSTYLE_SQL_STANDARD 2
31
#define INTSTYLE_ISO_8601 3
33
#define INTERVAL_FULL_RANGE (0x7FFF)
34
#define INTERVAL_MASK(b) (1 << (b))
35
#define MAX_INTERVAL_PRECISION 6
37
#define DTERR_BAD_FORMAT (-1)
38
#define DTERR_FIELD_OVERFLOW (-2)
39
#define DTERR_MD_FIELD_OVERFLOW (-3) /* triggers hint about DateStyle */
40
#define DTERR_INTERVAL_OVERFLOW (-4)
41
#define DTERR_TZDISP_OVERFLOW (-5)
46
#define INVALID "invalid"
47
#define EARLY "-infinity"
48
#define LATE "infinity"
51
#define TOMORROW "tomorrow"
52
#define YESTERDAY "yesterday"
55
#define DMICROSEC "usecond"
56
#define DMILLISEC "msecond"
57
#define DSECOND "second"
58
#define DMINUTE "minute"
62
#define DMONTH "month"
63
#define DQUARTER "quarter"
65
#define DDECADE "decade"
66
#define DCENTURY "century"
67
#define DMILLENNIUM "millennium"
70
#define DTIMEZONE "timezone"
71
#define DCURRENT "current"
74
* Fundamental time field definitions for parsing.
76
* Meridian: am, pm, or 24-hour style.
88
* Fields for time decoding.
90
* Can't have more of these than there are bits in an unsigned int
91
* since these are turned into bit masks during parsing and decoding.
93
* Furthermore, the values for YEAR, MONTH, DAY, HOUR, MINUTE, SECOND
94
* must be in the range 0..14 so that the associated bitmasks can fit
95
* into the left half of an INTERVAL's typmod value.
97
* Copy&pasted these values from src/include/utils/datetime.h
98
* 2008-11-20, changing a number of their values.
114
#define MILLISECOND 13
115
#define MICROSECOND 14
120
/* these are only for relative dates */
122
#define ABS_BEFORE 20
124
/* generic fields to help with parsing */
127
/* reserved for unrecognized string values */
128
#define UNKNOWN_FIELD 31
132
* Token field definitions for time parsing and decoding.
133
* These need to fit into the datetkn table type.
134
* At the moment, that means keep them within [-127,127].
135
* These are also used for bit masks in DecodeDateDelta()
136
* so actually restrict them to within [0,31] for now.
138
* Not all of these fields are used for masks in DecodeDateDelta
139
* so allow some larger than 31. - thomas 1997-11-17
150
#define DTK_SPECIAL 6
151
#define DTK_INVALID 7
152
#define DTK_CURRENT 8
157
#define DTK_YESTERDAY 13
159
#define DTK_TOMORROW 15
163
#define DTK_SECOND 18
164
#define DTK_MINUTE 19
169
#define DTK_QUARTER 24
171
#define DTK_DECADE 26
172
#define DTK_CENTURY 27
173
#define DTK_MILLENNIUM 28
174
#define DTK_MILLISEC 29
175
#define DTK_MICROSEC 30
176
#define DTK_JULIAN 31
180
#define DTK_TZ_HOUR 34
181
#define DTK_TZ_MINUTE 35
182
#define DTK_ISOYEAR 36
183
#define DTK_ISODOW 37
187
* Bit mask definitions for time parsing.
189
/* Copy&pasted these values from src/include/utils/datetime.h */
190
#define DTK_M(t) (0x01 << (t))
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_M(SECOND))
195
#define MAXDATELEN 63 /* maximum possible length of an input date
196
* string (not counting tr. null) */
197
#define MAXDATEFIELDS 25 /* maximum possible number of fields in a date
199
#define TOKMAXLEN 10 /* only this many chars are stored in
202
/* keep this struct small; it gets used a lot */
208
char token[TOKMAXLEN];
211
char value; /* this may be unsigned, alas */
216
* Macro to replace modf(), which is broken on some platforms.
217
* t = input and remainder
221
#define FMODULO(t,q,u) \
223
(q) = (((t) < 0) ? ceil((t) / (u)): floor((t) / (u))); \
224
if ((q) != 0) (t) -= rint((q) * (u)); \
228
* Like FMODULO(), but work on the timestamp datatype (either int64 or float8).
229
* We assume that int64 follows the C99 semantics for division (negative
230
* quotients truncate towards zero).
232
#ifdef HAVE_INT64_TIMESTAMP
233
#define TMODULO(t,q,u) \
236
if ((q) != 0) (t) -= ((q) * (u)); \
239
#define TMODULO(t,q,u) \
241
(q) = (((t) < 0) ? ceil((t) / (u)): floor((t) / (u))); \
242
if ((q) != 0) (t) -= rint((q) * (u)); \
246
/* in both timestamp.h and ecpg/dt.h */
247
#define DAYS_PER_YEAR 365.25 /* assumes leap year every four years */
248
#define MONTHS_PER_YEAR 12
250
* DAYS_PER_MONTH is very imprecise. The more accurate value is
251
* 365.2425/12 = 30.436875, or '30 days 10:29:06'. Right now we only
252
* return an integral number of days, but someday perhaps we should
253
* also return a 'time' value to be used as well. ISO 8601 suggests
256
#define DAYS_PER_MONTH 30 /* assumes exactly 30 days per month */
257
#define HOURS_PER_DAY 24 /* assume no daylight savings time changes */
260
* This doesn't adjust for uneven daylight savings time intervals or leap
261
* seconds, and it crudely estimates leap years. A more accurate value
262
* for days per years is 365.2422.
264
#define SECS_PER_YEAR (36525 * 864) /* avoid floating-point computation */
265
#define SECS_PER_DAY 86400
266
#define SECS_PER_HOUR 3600
267
#define SECS_PER_MINUTE 60
268
#define MINS_PER_HOUR 60
270
#ifdef HAVE_INT64_TIMESTAMP
271
#define USECS_PER_DAY INT64CONST(86400000000)
272
#define USECS_PER_HOUR INT64CONST(3600000000)
273
#define USECS_PER_MINUTE INT64CONST(60000000)
274
#define USECS_PER_SEC INT64CONST(1000000)
278
* Date/time validation
279
* Include check for leap year.
281
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
283
/* Julian date support for date2j() and j2date()
285
* IS_VALID_JULIAN checks the minimum date exactly, but is a bit sloppy
286
* about the maximum, since it's far enough out to not be especially
290
#define JULIAN_MINYEAR (-4713)
291
#define JULIAN_MINMONTH (11)
292
#define JULIAN_MINDAY (24)
293
#define JULIAN_MAXYEAR (5874898)
295
#define IS_VALID_JULIAN(y,m,d) ((((y) > JULIAN_MINYEAR) \
296
|| (((y) == JULIAN_MINYEAR) && (((m) > JULIAN_MINMONTH) \
297
|| (((m) == JULIAN_MINMONTH) && ((d) >= JULIAN_MINDAY))))) \
298
&& ((y) < JULIAN_MAXYEAR))
300
#define UTIME_MINYEAR (1901)
301
#define UTIME_MINMONTH (12)
302
#define UTIME_MINDAY (14)
303
#define UTIME_MAXYEAR (2038)
304
#define UTIME_MAXMONTH (01)
305
#define UTIME_MAXDAY (18)
307
#define IS_VALID_UTIME(y,m,d) ((((y) > UTIME_MINYEAR) \
308
|| (((y) == UTIME_MINYEAR) && (((m) > UTIME_MINMONTH) \
309
|| (((m) == UTIME_MINMONTH) && ((d) >= UTIME_MINDAY))))) \
310
&& (((y) < UTIME_MAXYEAR) \
311
|| (((y) == UTIME_MAXYEAR) && (((m) < UTIME_MAXMONTH) \
312
|| (((m) == UTIME_MAXMONTH) && ((d) <= UTIME_MAXDAY))))))
314
#ifdef HAVE_INT64_TIMESTAMP
316
#define DT_NOBEGIN (-INT64CONST(0x7fffffffffffffff) - 1)
317
#define DT_NOEND (INT64CONST(0x7fffffffffffffff))
321
#define DT_NOBEGIN (-HUGE_VAL)
322
#define DT_NOEND (HUGE_VAL)
324
#define DT_NOBEGIN (-DBL_MAX)
325
#define DT_NOEND (DBL_MAX)
327
#endif /* HAVE_INT64_TIMESTAMP */
329
#define TIMESTAMP_NOBEGIN(j) do {(j) = DT_NOBEGIN;} while (0)
330
#define TIMESTAMP_NOEND(j) do {(j) = DT_NOEND;} while (0)
331
#define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN)
332
#define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND)
333
#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
335
int DecodeTimeOnly(char **, int *, int, int *, struct tm *, fsec_t *, int *);
336
int DecodeInterval(char **, int *, int, int *, struct tm *, fsec_t *);
337
int DecodeTime(char *, int, int *, struct tm *, fsec_t *);
338
int EncodeTimeOnly(struct tm *, fsec_t, int *, int, char *);
339
int EncodeDateTime(struct tm *, fsec_t, int *, char **, int, char *, bool);
340
int EncodeInterval(struct tm *, fsec_t, int, char *);
341
int tm2timestamp(struct tm *, fsec_t, int *, timestamp *);
342
int DecodeUnits(int field, char *lowtoken, int *val);
343
bool CheckDateTokenTables(void);
344
int EncodeDateOnly(struct tm *, int, char *, bool);
345
int GetEpochTime(struct tm *);
346
int ParseDateTime(char *, char *, char **, int *, int, int *, char **);
347
int DecodeDateTime(char **, int *, int, int *, struct tm *, fsec_t *, bool);
348
void j2date(int, int *, int *, int *);
349
void GetCurrentDateTime(struct tm *);
350
int date2j(int, int, int);
351
void TrimTrailingZeros(char *);
352
void dt2time(double, int *, int *, int *, fsec_t *);
354
extern char *pgtypes_date_weekdays_short[];
355
extern char *pgtypes_date_months[];
356
extern char *months[];
358
extern int day_tab[2][13];