datetime.h 6.85 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * datetime.h
4 5 6
 *	  Definitions for the date/time and other date/time support code.
 *	  The support code is shared with other date data types,
 *	   including abstime, reltime, date, and time.
7 8
 *
 *
Bruce Momjian's avatar
Add:  
Bruce Momjian committed
9 10
 * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
 * Portions Copyright (c) 1994, Regents of the University of California
11
 *
12
 * $Id: datetime.h,v 1.16 2001/01/18 07:22:42 thomas Exp $
13 14 15 16 17 18
 *
 *-------------------------------------------------------------------------
 */
#ifndef DATETIME_H
#define DATETIME_H

19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
#include <time.h>
#include <math.h>
#include <limits.h>
#include "utils/timestamp.h"


/* ----------------------------------------------------------------
 *				time types + support macros
 *
 * String definitions for standard time quantities.
 *
 * These strings are the defaults used to form output time strings.
 * Other alternate forms are hardcoded into token tables in datetime.c.
 * ----------------------------------------------------------------
 */

#define DAGO			"ago"
#define DCURRENT		"current"
#define EPOCH			"epoch"
#define INVALID			"invalid"
#define EARLY			"-infinity"
#define LATE			"infinity"
#define NOW				"now"
#define TODAY			"today"
#define TOMORROW		"tomorrow"
#define YESTERDAY		"yesterday"
#define ZULU			"zulu"

#define DMICROSEC		"usecond"
#define DMILLISEC		"msecond"
#define DSECOND			"second"
#define DMINUTE			"minute"
#define DHOUR			"hour"
#define DDAY			"day"
#define DWEEK			"week"
#define DMONTH			"month"
#define DQUARTER		"quarter"
#define DYEAR			"year"
#define DDECADE			"decade"
#define DCENTURY		"century"
59
#define DMILLENNIUM		"millennium"
60 61 62 63 64 65 66 67
#define DA_D			"ad"
#define DB_C			"bc"
#define DTIMEZONE		"timezone"

/*
 * Fundamental time field definitions for parsing.
 *
 *	Meridian:  am, pm, or 24-hour style.
68
 *	Millennium: ad, bc
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
 */

#define AM		0
#define PM		1
#define HR24	2

#define AD		0
#define BC		1

/*
 * Fields for time decoding.
 * Can't have more of these than there are bits in an unsigned int
 *	since these are turned into bit masks during parsing and decoding.
 */

#define RESERV	0
#define MONTH	1
#define YEAR	2
#define DAY		3
#define TIMES	4				/* not used - thomas 1997-07-14 */
#define TZ		5
#define DTZ		6
#define DTZMOD	7
#define IGNORE	8
#define AMPM	9
#define HOUR	10
#define MINUTE	11
#define SECOND	12
#define DOY		13
#define DOW		14
#define UNITS	15
#define ADBC	16
/* these are only for relative dates */
#define AGO		17
#define ABS_BEFORE		18
#define ABS_AFTER		19

/*
 * Token field definitions for time parsing and decoding.
 * These need to fit into the datetkn table type.
 * At the moment, that means keep them within [-127,127].
 * These are also used for bit masks in DecodeDateDelta()
 *	so actually restrict them to within [0,31] for now.
 * - thomas 97/06/19
 * Not all of these fields are used for masks in DecodeDateDelta
 *	so allow some larger than 31. - thomas 1997-11-17
 */

#define DTK_NUMBER		0
#define DTK_STRING		1

#define DTK_DATE		2
#define DTK_TIME		3
#define DTK_TZ			4
#define DTK_AGO			5

#define DTK_SPECIAL		6
#define DTK_INVALID		7
#define DTK_CURRENT		8
#define DTK_EARLY		9
#define DTK_LATE		10
#define DTK_EPOCH		11
#define DTK_NOW			12
#define DTK_YESTERDAY	13
#define DTK_TODAY		14
#define DTK_TOMORROW	15
#define DTK_ZULU		16

#define DTK_DELTA		17
#define DTK_SECOND		18
#define DTK_MINUTE		19
#define DTK_HOUR		20
#define DTK_DAY			21
#define DTK_WEEK		22
#define DTK_MONTH		23
#define DTK_QUARTER		24
#define DTK_YEAR		25
#define DTK_DECADE		26
#define DTK_CENTURY		27
148
#define DTK_MILLENNIUM	28
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
#define DTK_MILLISEC	29
#define DTK_MICROSEC	30

#define DTK_DOW			32
#define DTK_DOY			33
#define DTK_TZ_HOUR		34
#define DTK_TZ_MINUTE	35

/*
 * Bit mask definitions for time parsing.
 */

#define DTK_M(t)		(0x01 << (t))

#define DTK_DATE_M		(DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
#define DTK_TIME_M		(DTK_M(HOUR) | DTK_M(MINUTE) | DTK_M(SECOND))

166 167
#define MAXDATELEN		51		/* maximum possible length of an input
								 * date string (not counting tr. null) */
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
#define MAXDATEFIELDS	25		/* maximum possible number of fields in a
								 * date string */
#define TOKMAXLEN		10		/* only this many chars are stored in
								 * datetktbl */

/* keep this struct small; it gets used a lot */
typedef struct
{
#if defined(_AIX)
	char	   *token;
#else
	char		token[TOKMAXLEN];
#endif	 /* _AIX */
	char		type;
	char		value;			/* this may be unsigned, alas */
} datetkn;


/* TMODULO()
 * Macro to replace modf(), which is broken on some platforms.
 */
#define TMODULO(t,q,u) \
do { \
	q = ((t < 0)? ceil(t / u): floor(t / u)); \
	if (q != 0) \
		t -= rint(q * u); \
} while(0)

196 197 198 199 200
#ifdef __CYGWIN__
#define TIMEZONE_GLOBAL _timezone
#else
#define TIMEZONE_GLOBAL timezone
#endif
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243

/*
 * Date/time validation
 * Include check for leap year.
 */

extern int	day_tab[2][13];

#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))

/* Julian date support for date2j() and j2date()
 * Set the minimum year to one greater than the year of the first valid day
 *	to avoid having to check year and day both. - tgl 97/05/08
 */

#define JULIAN_MINYEAR (-4713)
#define JULIAN_MINMONTH (11)
#define JULIAN_MINDAY (23)

#define IS_VALID_JULIAN(y,m,d) ((y > JULIAN_MINYEAR) \
 || ((y == JULIAN_MINYEAR) && ((m > JULIAN_MINMONTH) \
  || ((m == JULIAN_MINMONTH) && (d >= JULIAN_MINDAY)))))

#define UTIME_MINYEAR (1901)
#define UTIME_MINMONTH (12)
#define UTIME_MINDAY (14)
#define UTIME_MAXYEAR (2038)
#define UTIME_MAXMONTH (01)
#define UTIME_MAXDAY (18)

#define IS_VALID_UTIME(y,m,d) (((y > UTIME_MINYEAR) \
 || ((y == UTIME_MINYEAR) && ((m > UTIME_MINMONTH) \
  || ((m == UTIME_MINMONTH) && (d >= UTIME_MINDAY))))) \
 && ((y < UTIME_MAXYEAR) \
 || ((y == UTIME_MAXYEAR) && ((m < UTIME_MAXMONTH) \
  || ((m == UTIME_MAXMONTH) && (d <= UTIME_MAXDAY))))))


extern void GetCurrentTime(struct tm * tm);
extern void j2date(int jd, int *year, int *month, int *day);
extern int	date2j(int year, int month, int day);

extern int ParseDateTime(char *timestr, char *lowstr,
244 245
			  char **field, int *ftype,
			  int maxfields, int *numfields);
246
extern int DecodeDateTime(char **field, int *ftype,
247 248
			   int nf, int *dtype,
			   struct tm * tm, double *fsec, int *tzp);
249

250
extern int DecodeTimeOnly(char **field, int *ftype,
251 252
			   int nf, int *dtype,
			   struct tm * tm, double *fsec, int *tzp);
253 254

extern int DecodeDateDelta(char **field, int *ftype,
255 256
				int nf, int *dtype,
				struct tm * tm, double *fsec);
257

258 259 260 261
extern int	EncodeDateOnly(struct tm * tm, int style, char *str);
extern int	EncodeTimeOnly(struct tm * tm, double fsec, int *tzp, int style, char *str);
extern int	EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, char *str);
extern int	EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str);
262

263 264
extern int	DecodeSpecial(int field, char *lowtoken, int *val);
extern int	DecodeUnits(int field, char *lowtoken, int *val);
265

266
extern int	j2day(int jd);
267

268
#endif	 /* DATETIME_H */