1 /* src/interfaces/ecpg/pgtypeslib/dt.h */
2 
3 #ifndef DT_H
4 #define DT_H
5 
6 #include <pgtypes_timestamp.h>
7 
8 #define MAXTZLEN			 10
9 
10 typedef int32 fsec_t;
11 
12 #define USE_POSTGRES_DATES				0
13 #define USE_ISO_DATES					1
14 #define USE_SQL_DATES					2
15 #define USE_GERMAN_DATES				3
16 
17 #define INTSTYLE_POSTGRES			  0
18 #define INTSTYLE_POSTGRES_VERBOSE	  1
19 #define INTSTYLE_SQL_STANDARD		  2
20 #define INTSTYLE_ISO_8601			  3
21 
22 #define INTERVAL_FULL_RANGE (0x7FFF)
23 #define INTERVAL_MASK(b) (1 << (b))
24 #define MAX_INTERVAL_PRECISION 6
25 
26 #define DTERR_BAD_FORMAT		(-1)
27 #define DTERR_FIELD_OVERFLOW	(-2)
28 #define DTERR_MD_FIELD_OVERFLOW (-3)	/* triggers hint about DateStyle */
29 #define DTERR_INTERVAL_OVERFLOW (-4)
30 #define DTERR_TZDISP_OVERFLOW	(-5)
31 
32 
33 #define DAGO			"ago"
34 #define DCURRENT		"current"
35 #define EPOCH			"epoch"
36 #define INVALID			"invalid"
37 #define EARLY			"-infinity"
38 #define LATE			"infinity"
39 #define NOW				"now"
40 #define TODAY			"today"
41 #define TOMORROW		"tomorrow"
42 #define YESTERDAY		"yesterday"
43 #define ZULU			"zulu"
44 
45 #define DMICROSEC		"usecond"
46 #define DMILLISEC		"msecond"
47 #define DSECOND			"second"
48 #define DMINUTE			"minute"
49 #define DHOUR			"hour"
50 #define DDAY			"day"
51 #define DWEEK			"week"
52 #define DMONTH			"month"
53 #define DQUARTER		"quarter"
54 #define DYEAR			"year"
55 #define DDECADE			"decade"
56 #define DCENTURY		"century"
57 #define DMILLENNIUM		"millennium"
58 #define DA_D			"ad"
59 #define DB_C			"bc"
60 #define DTIMEZONE		"timezone"
61 
62 /*
63  * Fundamental time field definitions for parsing.
64  *
65  *	Meridian:  am, pm, or 24-hour style.
66  *	Millennium: ad, bc
67  */
68 
69 #define AM		0
70 #define PM		1
71 #define HR24	2
72 
73 #define AD		0
74 #define BC		1
75 
76 /*
77  * Field types for time decoding.
78  *
79  * Can't have more of these than there are bits in an unsigned int
80  * since these are turned into bit masks during parsing and decoding.
81  *
82  * Furthermore, the values for YEAR, MONTH, DAY, HOUR, MINUTE, SECOND
83  * must be in the range 0..14 so that the associated bitmasks can fit
84  * into the left half of an INTERVAL's typmod value.
85  *
86  * Copy&pasted these values from src/include/utils/datetime.h
87  * 2008-11-20, changing a number of their values.
88  */
89 
90 #define RESERV	0
91 #define MONTH	1
92 #define YEAR	2
93 #define DAY		3
94 #define JULIAN	4
95 #define TZ		5				/* fixed-offset timezone abbreviation */
96 #define DTZ		6				/* fixed-offset timezone abbrev, DST */
97 #define DYNTZ	7				/* dynamic timezone abbr (unimplemented) */
98 #define IGNORE_DTF	8
99 #define AMPM	9
100 #define HOUR	10
101 #define MINUTE	11
102 #define SECOND	12
103 #define MILLISECOND 13
104 #define MICROSECOND 14
105 #define DOY		15
106 #define DOW		16
107 #define UNITS	17
108 #define ADBC	18
109 /* these are only for relative dates */
110 #define AGO		19
111 #define ABS_BEFORE		20
112 #define ABS_AFTER		21
113 /* generic fields to help with parsing */
114 #define ISODATE 22
115 #define ISOTIME 23
116 /* hack for parsing two-word timezone specs "MET DST" etc */
117 #define DTZMOD	28				/* "DST" as a separate word */
118 /* reserved for unrecognized string values */
119 #define UNKNOWN_FIELD	31
120 
121 
122 /*
123  * Token field definitions for time parsing and decoding.
124  *
125  * Some field type codes (see above) use these as the "value" in datetktbl[].
126  * These are also used for bit masks in DecodeDateTime and friends
127  *	so actually restrict them to within [0,31] for now.
128  * - thomas 97/06/19
129  * Not all of these fields are used for masks in DecodeDateTime
130  *	so allow some larger than 31. - thomas 1997-11-17
131  *
132  * Caution: there are undocumented assumptions in the code that most of these
133  * values are not equal to IGNORE_DTF nor RESERV.  Be very careful when
134  * renumbering values in either of these apparently-independent lists :-(
135  */
136 
137 #define DTK_NUMBER		0
138 #define DTK_STRING		1
139 
140 #define DTK_DATE		2
141 #define DTK_TIME		3
142 #define DTK_TZ			4
143 #define DTK_AGO			5
144 
145 #define DTK_SPECIAL		6
146 #define DTK_INVALID		7
147 #define DTK_CURRENT		8
148 #define DTK_EARLY		9
149 #define DTK_LATE		10
150 #define DTK_EPOCH		11
151 #define DTK_NOW			12
152 #define DTK_YESTERDAY	13
153 #define DTK_TODAY		14
154 #define DTK_TOMORROW	15
155 #define DTK_ZULU		16
156 
157 #define DTK_DELTA		17
158 #define DTK_SECOND		18
159 #define DTK_MINUTE		19
160 #define DTK_HOUR		20
161 #define DTK_DAY			21
162 #define DTK_WEEK		22
163 #define DTK_MONTH		23
164 #define DTK_QUARTER		24
165 #define DTK_YEAR		25
166 #define DTK_DECADE		26
167 #define DTK_CENTURY		27
168 #define DTK_MILLENNIUM	28
169 #define DTK_MILLISEC	29
170 #define DTK_MICROSEC	30
171 #define DTK_JULIAN		31
172 
173 #define DTK_DOW			32
174 #define DTK_DOY			33
175 #define DTK_TZ_HOUR		34
176 #define DTK_TZ_MINUTE	35
177 #define DTK_ISOYEAR		36
178 #define DTK_ISODOW		37
179 
180 
181 /*
182  * Bit mask definitions for time parsing.
183  */
184 /* Copy&pasted these values from src/include/utils/datetime.h */
185 #define DTK_M(t)		(0x01 << (t))
186 #define DTK_ALL_SECS_M	   (DTK_M(SECOND) | DTK_M(MILLISECOND) | DTK_M(MICROSECOND))
187 #define DTK_DATE_M		(DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
188 #define DTK_TIME_M		(DTK_M(HOUR) | DTK_M(MINUTE) | DTK_M(SECOND))
189 
190 /*
191  * Working buffer size for input and output of interval, timestamp, etc.
192  * Inputs that need more working space will be rejected early.  Longer outputs
193  * will overrun buffers, so this must suffice for all possible output.  As of
194  * this writing, PGTYPESinterval_to_asc() needs the most space at ~90 bytes.
195  */
196 #define MAXDATELEN		128
197 /* maximum possible number of fields in a date string */
198 #define MAXDATEFIELDS	25
199 /* only this many chars are stored in datetktbl */
200 #define TOKMAXLEN		10
201 
202 /* keep this struct small; it gets used a lot */
203 typedef struct
204 {
205 	char		token[TOKMAXLEN + 1];	/* always NUL-terminated */
206 	char		type;			/* see field type codes above */
207 	int32		value;			/* meaning depends on type */
208 } datetkn;
209 
210 
211 /* FMODULO()
212  * Macro to replace modf(), which is broken on some platforms.
213  * t = input and remainder
214  * q = integer part
215  * u = divisor
216  */
217 #define FMODULO(t,q,u) \
218 do { \
219 	(q) = (((t) < 0) ? ceil((t) / (u)): floor((t) / (u))); \
220 	if ((q) != 0) (t) -= rint((q) * (u)); \
221 } while(0)
222 
223 /* TMODULO()
224  * Like FMODULO(), but work on the timestamp datatype (now always int64).
225  * We assume that int64 follows the C99 semantics for division (negative
226  * quotients truncate towards zero).
227  */
228 #define TMODULO(t,q,u) \
229 do { \
230 	(q) = ((t) / (u)); \
231 	if ((q) != 0) (t) -= ((q) * (u)); \
232 } while(0)
233 
234 /* in both timestamp.h and ecpg/dt.h */
235 #define DAYS_PER_YEAR	365.25	/* assumes leap year every four years */
236 #define MONTHS_PER_YEAR 12
237 /*
238  *	DAYS_PER_MONTH is very imprecise.  The more accurate value is
239  *	365.2425/12 = 30.436875, or '30 days 10:29:06'.  Right now we only
240  *	return an integral number of days, but someday perhaps we should
241  *	also return a 'time' value to be used as well.  ISO 8601 suggests
242  *	30 days.
243  */
244 #define DAYS_PER_MONTH	30		/* assumes exactly 30 days per month */
245 #define HOURS_PER_DAY	24		/* assume no daylight savings time changes */
246 
247 /*
248  *	This doesn't adjust for uneven daylight savings time intervals or leap
249  *	seconds, and it crudely estimates leap years.  A more accurate value
250  *	for days per years is 365.2422.
251  */
252 #define SECS_PER_YEAR	(36525 * 864)	/* avoid floating-point computation */
253 #define SECS_PER_DAY	86400
254 #define SECS_PER_HOUR	3600
255 #define SECS_PER_MINUTE 60
256 #define MINS_PER_HOUR	60
257 
258 #define USECS_PER_DAY	INT64CONST(86400000000)
259 #define USECS_PER_HOUR	INT64CONST(3600000000)
260 #define USECS_PER_MINUTE INT64CONST(60000000)
261 #define USECS_PER_SEC	INT64CONST(1000000)
262 
263 /*
264  * Date/time validation
265  * Include check for leap year.
266  */
267 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
268 
269 /*
270  * Julian date support --- see comments in backend's timestamp.h.
271  */
272 
273 #define JULIAN_MINYEAR (-4713)
274 #define JULIAN_MINMONTH (11)
275 #define JULIAN_MINDAY (24)
276 #define JULIAN_MAXYEAR (5874898)
277 #define JULIAN_MAXMONTH (6)
278 #define JULIAN_MAXDAY (3)
279 
280 #define IS_VALID_JULIAN(y,m,d) \
281 	(((y) > JULIAN_MINYEAR || \
282 	  ((y) == JULIAN_MINYEAR && ((m) >= JULIAN_MINMONTH))) && \
283 	 ((y) < JULIAN_MAXYEAR || \
284 	  ((y) == JULIAN_MAXYEAR && ((m) < JULIAN_MAXMONTH))))
285 
286 #define MIN_TIMESTAMP	INT64CONST(-211813488000000000)
287 #define END_TIMESTAMP	INT64CONST(9223371331200000000)
288 
289 #define IS_VALID_TIMESTAMP(t)  (MIN_TIMESTAMP <= (t) && (t) < END_TIMESTAMP)
290 
291 #define UTIME_MINYEAR (1901)
292 #define UTIME_MINMONTH (12)
293 #define UTIME_MINDAY (14)
294 #define UTIME_MAXYEAR (2038)
295 #define UTIME_MAXMONTH (01)
296 #define UTIME_MAXDAY (18)
297 
298 #define IS_VALID_UTIME(y,m,d) ((((y) > UTIME_MINYEAR) \
299  || (((y) == UTIME_MINYEAR) && (((m) > UTIME_MINMONTH) \
300   || (((m) == UTIME_MINMONTH) && ((d) >= UTIME_MINDAY))))) \
301  && (((y) < UTIME_MAXYEAR) \
302  || (((y) == UTIME_MAXYEAR) && (((m) < UTIME_MAXMONTH) \
303   || (((m) == UTIME_MAXMONTH) && ((d) <= UTIME_MAXDAY))))))
304 
305 #define DT_NOBEGIN		(-INT64CONST(0x7fffffffffffffff) - 1)
306 #define DT_NOEND		(INT64CONST(0x7fffffffffffffff))
307 
308 #define TIMESTAMP_NOBEGIN(j)	do {(j) = DT_NOBEGIN;} while (0)
309 #define TIMESTAMP_NOEND(j)			do {(j) = DT_NOEND;} while (0)
310 #define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN)
311 #define TIMESTAMP_IS_NOEND(j)	((j) == DT_NOEND)
312 #define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
313 
314 int			DecodeInterval(char **, int *, int, int *, struct tm *, fsec_t *);
315 int			DecodeTime(char *, int *, struct tm *, fsec_t *);
316 void		EncodeDateTime(struct tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str, bool EuroDates);
317 void		EncodeInterval(struct tm *tm, fsec_t fsec, int style, char *str);
318 int			tm2timestamp(struct tm *, fsec_t, int *, timestamp *);
319 int			DecodeUnits(int field, char *lowtoken, int *val);
320 bool		CheckDateTokenTables(void);
321 void		EncodeDateOnly(struct tm *tm, int style, char *str, bool EuroDates);
322 int			GetEpochTime(struct tm *);
323 int			ParseDateTime(char *, char *, char **, int *, int *, char **);
324 int			DecodeDateTime(char **, int *, int, int *, struct tm *, fsec_t *, bool);
325 void		j2date(int, int *, int *, int *);
326 void		GetCurrentDateTime(struct tm *);
327 int			date2j(int, int, int);
328 void		TrimTrailingZeros(char *);
329 void		dt2time(double, int *, int *, int *, fsec_t *);
330 int PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d,
331 							int *year, int *month, int *day,
332 							int *hour, int *minute, int *second,
333 							int *tz);
334 
335 extern char *pgtypes_date_weekdays_short[];
336 extern char *pgtypes_date_months[];
337 extern char *months[];
338 extern char *days[];
339 extern int	day_tab[2][13];
340 
341 #endif							/* DT_H */
342