1 /*-------------------------------------------------------------------------
4 * Timestamp and Interval typedefs and related macros.
6 * Note: this file must be includable in both frontend and backend contexts.
8 * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/include/datatype/timestamp.h
13 *-------------------------------------------------------------------------
15 #ifndef DATATYPE_TIMESTAMP_H
16 #define DATATYPE_TIMESTAMP_H
23 * Timestamp represents absolute time.
25 * Interval represents delta time. Keep track of months (and years), days,
26 * and hours/minutes/seconds separately since the elapsed time spanned is
27 * unknown until instantiated relative to an absolute time.
29 * Note that Postgres uses "time interval" to mean a bounded interval,
30 * consisting of a beginning and ending time, not a time span - thomas 97/03/20
32 * We have two implementations, one that uses int64 values with units of
33 * microseconds, and one that uses double values with units of seconds.
35 * TimeOffset and fsec_t are convenience typedefs for temporary variables
36 * that are of different types in the two cases. Do not use fsec_t in values
37 * stored on-disk, since it is not the same size in both implementations.
38 * Also, fsec_t is only meant for *fractional* seconds; beware of overflow
39 * if the value you need to store could be many seconds.
42 #ifdef HAVE_INT64_TIMESTAMP
44 typedef int64 Timestamp;
45 typedef int64 TimestampTz;
46 typedef int64 TimeOffset;
47 typedef int32 fsec_t; /* fractional seconds (in microseconds) */
50 typedef double Timestamp;
51 typedef double TimestampTz;
52 typedef double TimeOffset;
53 typedef double fsec_t; /* fractional seconds (in seconds) */
58 TimeOffset time; /* all time units other than days, months and
60 int32 day; /* days, after time for alignment */
61 int32 month; /* months and years, after time for alignment */
65 #define MAX_TIMESTAMP_PRECISION 6
66 #define MAX_INTERVAL_PRECISION 6
69 * Round off to MAX_TIMESTAMP_PRECISION decimal places.
70 * Note: this is also used for rounding off intervals.
72 #define TS_PREC_INV 1000000.0
73 #define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV)
77 * Assorted constants for datetime-related calculations
80 #define DAYS_PER_YEAR 365.25 /* assumes leap year every four years */
81 #define MONTHS_PER_YEAR 12
83 * DAYS_PER_MONTH is very imprecise. The more accurate value is
84 * 365.2425/12 = 30.436875, or '30 days 10:29:06'. Right now we only
85 * return an integral number of days, but someday perhaps we should
86 * also return a 'time' value to be used as well. ISO 8601 suggests
89 #define DAYS_PER_MONTH 30 /* assumes exactly 30 days per month */
90 #define HOURS_PER_DAY 24 /* assume no daylight savings time changes */
93 * This doesn't adjust for uneven daylight savings time intervals or leap
94 * seconds, and it crudely estimates leap years. A more accurate value
95 * for days per years is 365.2422.
97 #define SECS_PER_YEAR (36525 * 864) /* avoid floating-point computation */
98 #define SECS_PER_DAY 86400
99 #define SECS_PER_HOUR 3600
100 #define SECS_PER_MINUTE 60
101 #define MINS_PER_HOUR 60
103 #define USECS_PER_DAY INT64CONST(86400000000)
104 #define USECS_PER_HOUR INT64CONST(3600000000)
105 #define USECS_PER_MINUTE INT64CONST(60000000)
106 #define USECS_PER_SEC INT64CONST(1000000)
109 * We allow numeric timezone offsets up to 15:59:59 either way from Greenwich.
110 * Currently, the record holders for wackiest offsets in actual use are zones
111 * Asia/Manila, at -15:56:00 until 1844, and America/Metlakatla, at +15:13:42
112 * until 1867. If we were to reject such values we would fail to dump and
113 * restore old timestamptz values with these zone settings.
115 #define MAX_TZDISP_HOUR 15 /* maximum allowed hour part */
116 #define TZDISP_LIMIT ((MAX_TZDISP_HOUR + 1) * SECS_PER_HOUR)
119 * DT_NOBEGIN represents timestamp -infinity; DT_NOEND represents +infinity
121 #ifdef HAVE_INT64_TIMESTAMP
122 #define DT_NOBEGIN (-INT64CONST(0x7fffffffffffffff) - 1)
123 #define DT_NOEND (INT64CONST(0x7fffffffffffffff))
124 #else /* !HAVE_INT64_TIMESTAMP */
126 #define DT_NOBEGIN (-HUGE_VAL)
127 #define DT_NOEND (HUGE_VAL)
129 #define DT_NOBEGIN (-DBL_MAX)
130 #define DT_NOEND (DBL_MAX)
132 #endif /* HAVE_INT64_TIMESTAMP */
134 #define TIMESTAMP_NOBEGIN(j) \
135 do {(j) = DT_NOBEGIN;} while (0)
137 #define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN)
139 #define TIMESTAMP_NOEND(j) \
140 do {(j) = DT_NOEND;} while (0)
142 #define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND)
144 #define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
148 * Julian date support.
150 * IS_VALID_JULIAN checks the minimum date exactly, but is a bit sloppy
151 * about the maximum, since it's far enough out to not be especially
155 #define JULIAN_MINYEAR (-4713)
156 #define JULIAN_MINMONTH (11)
157 #define JULIAN_MINDAY (24)
158 #define JULIAN_MAXYEAR (5874898)
160 #define IS_VALID_JULIAN(y,m,d) \
161 (((y) > JULIAN_MINYEAR \
162 || ((y) == JULIAN_MINYEAR && \
163 ((m) > JULIAN_MINMONTH \
164 || ((m) == JULIAN_MINMONTH && (d) >= JULIAN_MINDAY)))) \
165 && (y) < JULIAN_MAXYEAR)
167 #define JULIAN_MAX (2147483494) /* == date2j(JULIAN_MAXYEAR, 1, 1) */
169 /* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */
170 #define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */
171 #define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */
173 #endif /* DATATYPE_TIMESTAMP_H */