00001 /*------------------------------------------------------------------------- 00002 * 00003 * timestamp.h 00004 * Timestamp and Interval typedefs and related macros. 00005 * 00006 * Note: this file must be includable in both frontend and backend contexts. 00007 * 00008 * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group 00009 * Portions Copyright (c) 1994, Regents of the University of California 00010 * 00011 * src/include/datatype/timestamp.h 00012 * 00013 *------------------------------------------------------------------------- 00014 */ 00015 #ifndef DATATYPE_TIMESTAMP_H 00016 #define DATATYPE_TIMESTAMP_H 00017 00018 #include <math.h> 00019 #include <limits.h> 00020 #include <float.h> 00021 00022 /* 00023 * Timestamp represents absolute time. 00024 * 00025 * Interval represents delta time. Keep track of months (and years), days, 00026 * and hours/minutes/seconds separately since the elapsed time spanned is 00027 * unknown until instantiated relative to an absolute time. 00028 * 00029 * Note that Postgres uses "time interval" to mean a bounded interval, 00030 * consisting of a beginning and ending time, not a time span - thomas 97/03/20 00031 * 00032 * We have two implementations, one that uses int64 values with units of 00033 * microseconds, and one that uses double values with units of seconds. 00034 * 00035 * TimeOffset and fsec_t are convenience typedefs for temporary variables 00036 * that are of different types in the two cases. Do not use fsec_t in values 00037 * stored on-disk, since it is not the same size in both implementations. 00038 * Also, fsec_t is only meant for *fractional* seconds; beware of overflow 00039 * if the value you need to store could be many seconds. 00040 */ 00041 00042 #ifdef HAVE_INT64_TIMESTAMP 00043 00044 typedef int64 Timestamp; 00045 typedef int64 TimestampTz; 00046 typedef int64 TimeOffset; 00047 typedef int32 fsec_t; /* fractional seconds (in microseconds) */ 00048 #else 00049 00050 typedef double Timestamp; 00051 typedef double TimestampTz; 00052 typedef double TimeOffset; 00053 typedef double fsec_t; /* fractional seconds (in seconds) */ 00054 #endif 00055 00056 typedef struct 00057 { 00058 TimeOffset time; /* all time units other than days, months and 00059 * years */ 00060 int32 day; /* days, after time for alignment */ 00061 int32 month; /* months and years, after time for alignment */ 00062 } Interval; 00063 00064 00065 #define MAX_TIMESTAMP_PRECISION 6 00066 #define MAX_INTERVAL_PRECISION 6 00067 00068 /* 00069 * Round off to MAX_TIMESTAMP_PRECISION decimal places. 00070 * Note: this is also used for rounding off intervals. 00071 */ 00072 #define TS_PREC_INV 1000000.0 00073 #define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV) 00074 00075 00076 /* 00077 * Assorted constants for datetime-related calculations 00078 */ 00079 00080 #define DAYS_PER_YEAR 365.25 /* assumes leap year every four years */ 00081 #define MONTHS_PER_YEAR 12 00082 /* 00083 * DAYS_PER_MONTH is very imprecise. The more accurate value is 00084 * 365.2425/12 = 30.436875, or '30 days 10:29:06'. Right now we only 00085 * return an integral number of days, but someday perhaps we should 00086 * also return a 'time' value to be used as well. ISO 8601 suggests 00087 * 30 days. 00088 */ 00089 #define DAYS_PER_MONTH 30 /* assumes exactly 30 days per month */ 00090 #define HOURS_PER_DAY 24 /* assume no daylight savings time changes */ 00091 00092 /* 00093 * This doesn't adjust for uneven daylight savings time intervals or leap 00094 * seconds, and it crudely estimates leap years. A more accurate value 00095 * for days per years is 365.2422. 00096 */ 00097 #define SECS_PER_YEAR (36525 * 864) /* avoid floating-point computation */ 00098 #define SECS_PER_DAY 86400 00099 #define SECS_PER_HOUR 3600 00100 #define SECS_PER_MINUTE 60 00101 #define MINS_PER_HOUR 60 00102 00103 #define USECS_PER_DAY INT64CONST(86400000000) 00104 #define USECS_PER_HOUR INT64CONST(3600000000) 00105 #define USECS_PER_MINUTE INT64CONST(60000000) 00106 #define USECS_PER_SEC INT64CONST(1000000) 00107 00108 /* 00109 * We allow numeric timezone offsets up to 15:59:59 either way from Greenwich. 00110 * Currently, the record holders for wackiest offsets in actual use are zones 00111 * Asia/Manila, at -15:56:00 until 1844, and America/Metlakatla, at +15:13:42 00112 * until 1867. If we were to reject such values we would fail to dump and 00113 * restore old timestamptz values with these zone settings. 00114 */ 00115 #define MAX_TZDISP_HOUR 15 /* maximum allowed hour part */ 00116 #define TZDISP_LIMIT ((MAX_TZDISP_HOUR + 1) * SECS_PER_HOUR) 00117 00118 /* 00119 * DT_NOBEGIN represents timestamp -infinity; DT_NOEND represents +infinity 00120 */ 00121 #ifdef HAVE_INT64_TIMESTAMP 00122 #define DT_NOBEGIN (-INT64CONST(0x7fffffffffffffff) - 1) 00123 #define DT_NOEND (INT64CONST(0x7fffffffffffffff)) 00124 #else /* !HAVE_INT64_TIMESTAMP */ 00125 #ifdef HUGE_VAL 00126 #define DT_NOBEGIN (-HUGE_VAL) 00127 #define DT_NOEND (HUGE_VAL) 00128 #else 00129 #define DT_NOBEGIN (-DBL_MAX) 00130 #define DT_NOEND (DBL_MAX) 00131 #endif 00132 #endif /* HAVE_INT64_TIMESTAMP */ 00133 00134 #define TIMESTAMP_NOBEGIN(j) \ 00135 do {(j) = DT_NOBEGIN;} while (0) 00136 00137 #define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN) 00138 00139 #define TIMESTAMP_NOEND(j) \ 00140 do {(j) = DT_NOEND;} while (0) 00141 00142 #define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND) 00143 00144 #define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j)) 00145 00146 00147 /* 00148 * Julian date support. 00149 * 00150 * IS_VALID_JULIAN checks the minimum date exactly, but is a bit sloppy 00151 * about the maximum, since it's far enough out to not be especially 00152 * interesting. 00153 */ 00154 00155 #define JULIAN_MINYEAR (-4713) 00156 #define JULIAN_MINMONTH (11) 00157 #define JULIAN_MINDAY (24) 00158 #define JULIAN_MAXYEAR (5874898) 00159 00160 #define IS_VALID_JULIAN(y,m,d) \ 00161 (((y) > JULIAN_MINYEAR \ 00162 || ((y) == JULIAN_MINYEAR && \ 00163 ((m) > JULIAN_MINMONTH \ 00164 || ((m) == JULIAN_MINMONTH && (d) >= JULIAN_MINDAY)))) \ 00165 && (y) < JULIAN_MAXYEAR) 00166 00167 #define JULIAN_MAX (2147483494) /* == date2j(JULIAN_MAXYEAR, 1, 1) */ 00168 00169 /* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */ 00170 #define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */ 00171 #define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */ 00172 00173 #endif /* DATATYPE_TIMESTAMP_H */