1 /* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt.h,v 1.43 2009/05/26 01:39:49 tgl Exp $ */
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 DecodeInterval(char **, int *, int, int *, struct tm *, fsec_t *);
336 int DecodeTime(char *, int *, struct tm *, fsec_t *);
337 int EncodeDateTime(struct tm *, fsec_t, int *, char **, int, char *, bool);
338 int EncodeInterval(struct tm *, fsec_t, int, char *);
339 int tm2timestamp(struct tm *, fsec_t, int *, timestamp *);
340 int DecodeUnits(int field, char *lowtoken, int *val);
341 bool CheckDateTokenTables(void);
342 int EncodeDateOnly(struct tm *, int, char *, bool);
343 int GetEpochTime(struct tm *);
344 int ParseDateTime(char *, char *, char **, int *, int *, char **);
345 int DecodeDateTime(char **, int *, int, int *, struct tm *, fsec_t *, bool);
346 void j2date(int, int *, int *, int *);
347 void GetCurrentDateTime(struct tm *);
348 int date2j(int, int, int);
349 void TrimTrailingZeros(char *);
350 void dt2time(double, int *, int *, int *, fsec_t *);
352 extern char *pgtypes_date_weekdays_short[];
353 extern char *pgtypes_date_months[];
354 extern char *months[];
356 extern int day_tab[2][13];