| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * timestamp.h |
| 4 | * Timestamp and Interval typedefs and related macros. |
| 5 | * |
| 6 | * Note: this file must be includable in both frontend and backend contexts. |
| 7 | * |
| 8 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 9 | * Portions Copyright (c) 1994, Regents of the University of California |
| 10 | * |
| 11 | * src/include/datatype/timestamp.h |
| 12 | * |
| 13 | *------------------------------------------------------------------------- |
| 14 | */ |
| 15 | #ifndef DATATYPE_TIMESTAMP_H |
| 16 | #define DATATYPE_TIMESTAMP_H |
| 17 | |
| 18 | /* |
| 19 | * Timestamp represents absolute time. |
| 20 | * |
| 21 | * Interval represents delta time. Keep track of months (and years), days, |
| 22 | * and hours/minutes/seconds separately since the elapsed time spanned is |
| 23 | * unknown until instantiated relative to an absolute time. |
| 24 | * |
| 25 | * Note that Postgres uses "time interval" to mean a bounded interval, |
| 26 | * consisting of a beginning and ending time, not a time span - thomas 97/03/20 |
| 27 | * |
| 28 | * Timestamps, as well as the h/m/s fields of intervals, are stored as |
| 29 | * int64 values with units of microseconds. (Once upon a time they were |
| 30 | * double values with units of seconds.) |
| 31 | * |
| 32 | * TimeOffset and fsec_t are convenience typedefs for temporary variables. |
| 33 | * Do not use fsec_t in values stored on-disk. |
| 34 | * Also, fsec_t is only meant for *fractional* seconds; beware of overflow |
| 35 | * if the value you need to store could be many seconds. |
| 36 | */ |
| 37 | |
| 38 | typedef int64 Timestamp; |
| 39 | typedef int64 TimestampTz; |
| 40 | typedef int64 TimeOffset; |
| 41 | typedef int32 fsec_t; /* fractional seconds (in microseconds) */ |
| 42 | |
| 43 | typedef struct |
| 44 | { |
| 45 | TimeOffset time; /* all time units other than days, months and |
| 46 | * years */ |
| 47 | int32 day; /* days, after time for alignment */ |
| 48 | int32 month; /* months and years, after time for alignment */ |
| 49 | } Interval; |
| 50 | |
| 51 | |
| 52 | /* Limits on the "precision" option (typmod) for these data types */ |
| 53 | #define MAX_TIMESTAMP_PRECISION 6 |
| 54 | #define MAX_INTERVAL_PRECISION 6 |
| 55 | |
| 56 | /* |
| 57 | * Round off to MAX_TIMESTAMP_PRECISION decimal places. |
| 58 | * Note: this is also used for rounding off intervals. |
| 59 | */ |
| 60 | #define TS_PREC_INV 1000000.0 |
| 61 | #define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV) |
| 62 | |
| 63 | |
| 64 | /* |
| 65 | * Assorted constants for datetime-related calculations |
| 66 | */ |
| 67 | |
| 68 | #define DAYS_PER_YEAR 365.25 /* assumes leap year every four years */ |
| 69 | #define MONTHS_PER_YEAR 12 |
| 70 | /* |
| 71 | * DAYS_PER_MONTH is very imprecise. The more accurate value is |
| 72 | * 365.2425/12 = 30.436875, or '30 days 10:29:06'. Right now we only |
| 73 | * return an integral number of days, but someday perhaps we should |
| 74 | * also return a 'time' value to be used as well. ISO 8601 suggests |
| 75 | * 30 days. |
| 76 | */ |
| 77 | #define DAYS_PER_MONTH 30 /* assumes exactly 30 days per month */ |
| 78 | #define HOURS_PER_DAY 24 /* assume no daylight savings time changes */ |
| 79 | |
| 80 | /* |
| 81 | * This doesn't adjust for uneven daylight savings time intervals or leap |
| 82 | * seconds, and it crudely estimates leap years. A more accurate value |
| 83 | * for days per years is 365.2422. |
| 84 | */ |
| 85 | #define SECS_PER_YEAR (36525 * 864) /* avoid floating-point computation */ |
| 86 | #define SECS_PER_DAY 86400 |
| 87 | #define SECS_PER_HOUR 3600 |
| 88 | #define SECS_PER_MINUTE 60 |
| 89 | #define MINS_PER_HOUR 60 |
| 90 | |
| 91 | #define USECS_PER_DAY INT64CONST(86400000000) |
| 92 | #define USECS_PER_HOUR INT64CONST(3600000000) |
| 93 | #define USECS_PER_MINUTE INT64CONST(60000000) |
| 94 | #define USECS_PER_SEC INT64CONST(1000000) |
| 95 | |
| 96 | /* |
| 97 | * We allow numeric timezone offsets up to 15:59:59 either way from Greenwich. |
| 98 | * Currently, the record holders for wackiest offsets in actual use are zones |
| 99 | * Asia/Manila, at -15:56:00 until 1844, and America/Metlakatla, at +15:13:42 |
| 100 | * until 1867. If we were to reject such values we would fail to dump and |
| 101 | * restore old timestamptz values with these zone settings. |
| 102 | */ |
| 103 | #define MAX_TZDISP_HOUR 15 /* maximum allowed hour part */ |
| 104 | #define TZDISP_LIMIT ((MAX_TZDISP_HOUR + 1) * SECS_PER_HOUR) |
| 105 | |
| 106 | /* |
| 107 | * DT_NOBEGIN represents timestamp -infinity; DT_NOEND represents +infinity |
| 108 | */ |
| 109 | #define DT_NOBEGIN PG_INT64_MIN |
| 110 | #define DT_NOEND PG_INT64_MAX |
| 111 | |
| 112 | #define TIMESTAMP_NOBEGIN(j) \ |
| 113 | do {(j) = DT_NOBEGIN;} while (0) |
| 114 | |
| 115 | #define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN) |
| 116 | |
| 117 | #define TIMESTAMP_NOEND(j) \ |
| 118 | do {(j) = DT_NOEND;} while (0) |
| 119 | |
| 120 | #define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND) |
| 121 | |
| 122 | #define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j)) |
| 123 | |
| 124 | |
| 125 | /* |
| 126 | * Julian date support. |
| 127 | * |
| 128 | * date2j() and j2date() nominally handle the Julian date range 0..INT_MAX, |
| 129 | * or 4714-11-24 BC to 5874898-06-03 AD. In practice, date2j() will work and |
| 130 | * give correct negative Julian dates for dates before 4714-11-24 BC as well. |
| 131 | * We rely on it to do so back to 4714-11-01 BC. Allowing at least one day's |
| 132 | * slop is necessary so that timestamp rotation doesn't produce dates that |
| 133 | * would be rejected on input. For example, '4714-11-24 00:00 GMT BC' is a |
| 134 | * legal timestamptz value, but in zones east of Greenwich it would print as |
| 135 | * sometime in the afternoon of 4714-11-23 BC; if we couldn't process such a |
| 136 | * date we'd have a dump/reload failure. So the idea is for IS_VALID_JULIAN |
| 137 | * to accept a slightly wider range of dates than we really support, and |
| 138 | * then we apply the exact checks in IS_VALID_DATE or IS_VALID_TIMESTAMP, |
| 139 | * after timezone rotation if any. To save a few cycles, we can make |
| 140 | * IS_VALID_JULIAN check only to the month boundary, since its exact cutoffs |
| 141 | * are not very critical in this scheme. |
| 142 | * |
| 143 | * It is correct that JULIAN_MINYEAR is -4713, not -4714; it is defined to |
| 144 | * allow easy comparison to tm_year values, in which we follow the convention |
| 145 | * that tm_year <= 0 represents abs(tm_year)+1 BC. |
| 146 | */ |
| 147 | |
| 148 | #define JULIAN_MINYEAR (-4713) |
| 149 | #define JULIAN_MINMONTH (11) |
| 150 | #define JULIAN_MINDAY (24) |
| 151 | #define JULIAN_MAXYEAR (5874898) |
| 152 | #define JULIAN_MAXMONTH (6) |
| 153 | #define JULIAN_MAXDAY (3) |
| 154 | |
| 155 | #define IS_VALID_JULIAN(y,m,d) \ |
| 156 | (((y) > JULIAN_MINYEAR || \ |
| 157 | ((y) == JULIAN_MINYEAR && ((m) >= JULIAN_MINMONTH))) && \ |
| 158 | ((y) < JULIAN_MAXYEAR || \ |
| 159 | ((y) == JULIAN_MAXYEAR && ((m) < JULIAN_MAXMONTH)))) |
| 160 | |
| 161 | /* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */ |
| 162 | #define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */ |
| 163 | #define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */ |
| 164 | |
| 165 | /* |
| 166 | * Range limits for dates and timestamps. |
| 167 | * |
| 168 | * We have traditionally allowed Julian day zero as a valid datetime value, |
| 169 | * so that is the lower bound for both dates and timestamps. |
| 170 | * |
| 171 | * The upper limit for dates is 5874897-12-31, which is a bit less than what |
| 172 | * the Julian-date code can allow. For timestamps, the upper limit is |
| 173 | * 294276-12-31. The int64 overflow limit would be a few days later; again, |
| 174 | * leaving some slop avoids worries about corner-case overflow, and provides |
| 175 | * a simpler user-visible definition. |
| 176 | */ |
| 177 | |
| 178 | /* First allowed date, and first disallowed date, in Julian-date form */ |
| 179 | #define DATETIME_MIN_JULIAN (0) |
| 180 | #define DATE_END_JULIAN (2147483494) /* == date2j(JULIAN_MAXYEAR, 1, 1) */ |
| 181 | #define TIMESTAMP_END_JULIAN (109203528) /* == date2j(294277, 1, 1) */ |
| 182 | |
| 183 | /* Timestamp limits */ |
| 184 | #define MIN_TIMESTAMP INT64CONST(-211813488000000000) |
| 185 | /* == (DATETIME_MIN_JULIAN - POSTGRES_EPOCH_JDATE) * USECS_PER_DAY */ |
| 186 | #define END_TIMESTAMP INT64CONST(9223371331200000000) |
| 187 | /* == (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE) * USECS_PER_DAY */ |
| 188 | |
| 189 | /* Range-check a date (given in Postgres, not Julian, numbering) */ |
| 190 | #define IS_VALID_DATE(d) \ |
| 191 | ((DATETIME_MIN_JULIAN - POSTGRES_EPOCH_JDATE) <= (d) && \ |
| 192 | (d) < (DATE_END_JULIAN - POSTGRES_EPOCH_JDATE)) |
| 193 | |
| 194 | /* Range-check a timestamp */ |
| 195 | #define IS_VALID_TIMESTAMP(t) (MIN_TIMESTAMP <= (t) && (t) < END_TIMESTAMP) |
| 196 | |
| 197 | #endif /* DATATYPE_TIMESTAMP_H */ |
| 198 | |