aboutsummaryrefslogtreecommitdiff
path: root/src/include/datatype/timestamp.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/datatype/timestamp.h')
-rw-r--r--src/include/datatype/timestamp.h163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/include/datatype/timestamp.h b/src/include/datatype/timestamp.h
new file mode 100644
index 00000000000..fa68dd9e190
--- /dev/null
+++ b/src/include/datatype/timestamp.h
@@ -0,0 +1,163 @@
+/*-------------------------------------------------------------------------
+ *
+ * timestamp.h
+ * Timestamp and Interval typedefs and related macros.
+ *
+ * Note: this file must be includable in both frontend and backend contexts.
+ *
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/datatype/timestamp.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef DATATYPE_TIMESTAMP_H
+#define DATATYPE_TIMESTAMP_H
+
+#include <math.h>
+#include <limits.h>
+#include <float.h>
+
+/*
+ * Timestamp represents absolute time.
+ *
+ * Interval represents delta time. Keep track of months (and years), days,
+ * and hours/minutes/seconds separately since the elapsed time spanned is
+ * unknown until instantiated relative to an absolute time.
+ *
+ * Note that Postgres uses "time interval" to mean a bounded interval,
+ * consisting of a beginning and ending time, not a time span - thomas 97/03/20
+ *
+ * We have two implementations, one that uses int64 values with units of
+ * microseconds, and one that uses double values with units of seconds.
+ *
+ * TimeOffset and fsec_t are convenience typedefs for temporary variables
+ * that are of different types in the two cases. Do not use fsec_t in values
+ * stored on-disk, since it is not the same size in both implementations.
+ * Also, fsec_t is only meant for *fractional* seconds; beware of overflow
+ * if the value you need to store could be many seconds.
+ */
+
+#ifdef HAVE_INT64_TIMESTAMP
+
+typedef int64 Timestamp;
+typedef int64 TimestampTz;
+typedef int64 TimeOffset;
+typedef int32 fsec_t; /* fractional seconds (in microseconds) */
+#else
+
+typedef double Timestamp;
+typedef double TimestampTz;
+typedef double TimeOffset;
+typedef double fsec_t; /* fractional seconds (in seconds) */
+#endif
+
+typedef struct
+{
+ TimeOffset time; /* all time units other than days, months and
+ * years */
+ int32 day; /* days, after time for alignment */
+ int32 month; /* months and years, after time for alignment */
+} Interval;
+
+
+#define MAX_TIMESTAMP_PRECISION 6
+#define MAX_INTERVAL_PRECISION 6
+
+/*
+ * Round off to MAX_TIMESTAMP_PRECISION decimal places.
+ * Note: this is also used for rounding off intervals.
+ */
+#define TS_PREC_INV 1000000.0
+#define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV)
+
+
+/*
+ * Assorted constants for datetime-related calculations
+ */
+
+#define DAYS_PER_YEAR 365.25 /* assumes leap year every four years */
+#define MONTHS_PER_YEAR 12
+/*
+ * DAYS_PER_MONTH is very imprecise. The more accurate value is
+ * 365.2425/12 = 30.436875, or '30 days 10:29:06'. Right now we only
+ * return an integral number of days, but someday perhaps we should
+ * also return a 'time' value to be used as well. ISO 8601 suggests
+ * 30 days.
+ */
+#define DAYS_PER_MONTH 30 /* assumes exactly 30 days per month */
+#define HOURS_PER_DAY 24 /* assume no daylight savings time changes */
+
+/*
+ * This doesn't adjust for uneven daylight savings time intervals or leap
+ * seconds, and it crudely estimates leap years. A more accurate value
+ * for days per years is 365.2422.
+ */
+#define SECS_PER_YEAR (36525 * 864) /* avoid floating-point computation */
+#define SECS_PER_DAY 86400
+#define SECS_PER_HOUR 3600
+#define SECS_PER_MINUTE 60
+#define MINS_PER_HOUR 60
+
+#define USECS_PER_DAY INT64CONST(86400000000)
+#define USECS_PER_HOUR INT64CONST(3600000000)
+#define USECS_PER_MINUTE INT64CONST(60000000)
+#define USECS_PER_SEC INT64CONST(1000000)
+
+/*
+ * DT_NOBEGIN represents timestamp -infinity; DT_NOEND represents +infinity
+ */
+#ifdef HAVE_INT64_TIMESTAMP
+#define DT_NOBEGIN (-INT64CONST(0x7fffffffffffffff) - 1)
+#define DT_NOEND (INT64CONST(0x7fffffffffffffff))
+#else /* !HAVE_INT64_TIMESTAMP */
+#ifdef HUGE_VAL
+#define DT_NOBEGIN (-HUGE_VAL)
+#define DT_NOEND (HUGE_VAL)
+#else
+#define DT_NOBEGIN (-DBL_MAX)
+#define DT_NOEND (DBL_MAX)
+#endif
+#endif /* HAVE_INT64_TIMESTAMP */
+
+#define TIMESTAMP_NOBEGIN(j) \
+ do {(j) = DT_NOBEGIN;} while (0)
+
+#define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN)
+
+#define TIMESTAMP_NOEND(j) \
+ do {(j) = DT_NOEND;} while (0)
+
+#define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND)
+
+#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
+
+
+/*
+ * Julian date support.
+ *
+ * IS_VALID_JULIAN checks the minimum date exactly, but is a bit sloppy
+ * about the maximum, since it's far enough out to not be especially
+ * interesting.
+ */
+
+#define JULIAN_MINYEAR (-4713)
+#define JULIAN_MINMONTH (11)
+#define JULIAN_MINDAY (24)
+#define JULIAN_MAXYEAR (5874898)
+
+#define IS_VALID_JULIAN(y,m,d) \
+ (((y) > JULIAN_MINYEAR \
+ || ((y) == JULIAN_MINYEAR && \
+ ((m) > JULIAN_MINMONTH \
+ || ((m) == JULIAN_MINMONTH && (d) >= JULIAN_MINDAY)))) \
+ && (y) < JULIAN_MAXYEAR)
+
+#define JULIAN_MAX (2147483494) /* == date2j(JULIAN_MAXYEAR, 1, 1) */
+
+/* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */
+#define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */
+#define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */
+
+#endif /* DATATYPE_TIMESTAMP_H */