📄 date.c
字号:
/*------------------------------------------------------------------------- * * date.c * implements DATE and TIME data types specified in SQL-92 standard * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * * IDENTIFICATION * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.122.2.1 2006/02/09 03:40:30 tgl Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include <ctype.h>#include <limits.h>#include <float.h>#include <time.h>#include "access/hash.h"#include "libpq/pqformat.h"#include "miscadmin.h"#include "parser/scansup.h"#include "utils/builtins.h"#include "utils/date.h"#include "utils/nabstime.h"#include "utils/timestamp.h"/* * gcc's -ffast-math switch breaks routines that expect exact results from * expressions like timeval / SECS_PER_HOUR, where timeval is double. */#ifdef __FAST_MATH__#error -ffast-math is known to break this code#endifstatic int time2tm(TimeADT time, struct pg_tm * tm, fsec_t *fsec);static int timetz2tm(TimeTzADT *time, struct pg_tm * tm, fsec_t *fsec, int *tzp);static int tm2time(struct pg_tm * tm, fsec_t fsec, TimeADT *result);static int tm2timetz(struct pg_tm * tm, fsec_t fsec, int tz, TimeTzADT *result);static void AdjustTimeForTypmod(TimeADT *time, int32 typmod);/***************************************************************************** * Date ADT *****************************************************************************//* date_in() * Given date text string, convert to internal date format. */Datumdate_in(PG_FUNCTION_ARGS){ char *str = PG_GETARG_CSTRING(0); DateADT date; fsec_t fsec; struct pg_tm tt, *tm = &tt; int tzp; int dtype; int nf; int dterr; char *field[MAXDATEFIELDS]; int ftype[MAXDATEFIELDS]; char workbuf[MAXDATELEN + 1]; dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field, ftype, MAXDATEFIELDS, &nf); if (dterr == 0) dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp); if (dterr != 0) DateTimeParseError(dterr, str, "date"); switch (dtype) { case DTK_DATE: break; case DTK_CURRENT: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("date/time value \"current\" is no longer supported"))); GetCurrentDateTime(tm); break; case DTK_EPOCH: GetEpochTime(tm); break; default: DateTimeParseError(DTERR_BAD_FORMAT, str, "date"); break; } if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday)) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("date out of range: \"%s\"", str))); date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE; PG_RETURN_DATEADT(date);}/* date_out() * Given internal format date, convert to text string. */Datumdate_out(PG_FUNCTION_ARGS){ DateADT date = PG_GETARG_DATEADT(0); char *result; struct pg_tm tt, *tm = &tt; char buf[MAXDATELEN + 1]; j2date(date + POSTGRES_EPOCH_JDATE, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday)); EncodeDateOnly(tm, DateStyle, buf); result = pstrdup(buf); PG_RETURN_CSTRING(result);}/* * date_recv - converts external binary format to date */Datumdate_recv(PG_FUNCTION_ARGS){ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); PG_RETURN_DATEADT((DateADT) pq_getmsgint(buf, sizeof(DateADT)));}/* * date_send - converts date to binary format */Datumdate_send(PG_FUNCTION_ARGS){ DateADT date = PG_GETARG_DATEADT(0); StringInfoData buf; pq_begintypsend(&buf); pq_sendint(&buf, date, sizeof(date)); PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}/* * Comparison functions for dates */Datumdate_eq(PG_FUNCTION_ARGS){ DateADT dateVal1 = PG_GETARG_DATEADT(0); DateADT dateVal2 = PG_GETARG_DATEADT(1); PG_RETURN_BOOL(dateVal1 == dateVal2);}Datumdate_ne(PG_FUNCTION_ARGS){ DateADT dateVal1 = PG_GETARG_DATEADT(0); DateADT dateVal2 = PG_GETARG_DATEADT(1); PG_RETURN_BOOL(dateVal1 != dateVal2);}Datumdate_lt(PG_FUNCTION_ARGS){ DateADT dateVal1 = PG_GETARG_DATEADT(0); DateADT dateVal2 = PG_GETARG_DATEADT(1); PG_RETURN_BOOL(dateVal1 < dateVal2);}Datumdate_le(PG_FUNCTION_ARGS){ DateADT dateVal1 = PG_GETARG_DATEADT(0); DateADT dateVal2 = PG_GETARG_DATEADT(1); PG_RETURN_BOOL(dateVal1 <= dateVal2);}Datumdate_gt(PG_FUNCTION_ARGS){ DateADT dateVal1 = PG_GETARG_DATEADT(0); DateADT dateVal2 = PG_GETARG_DATEADT(1); PG_RETURN_BOOL(dateVal1 > dateVal2);}Datumdate_ge(PG_FUNCTION_ARGS){ DateADT dateVal1 = PG_GETARG_DATEADT(0); DateADT dateVal2 = PG_GETARG_DATEADT(1); PG_RETURN_BOOL(dateVal1 >= dateVal2);}Datumdate_cmp(PG_FUNCTION_ARGS){ DateADT dateVal1 = PG_GETARG_DATEADT(0); DateADT dateVal2 = PG_GETARG_DATEADT(1); if (dateVal1 < dateVal2) PG_RETURN_INT32(-1); else if (dateVal1 > dateVal2) PG_RETURN_INT32(1); PG_RETURN_INT32(0);}Datumdate_larger(PG_FUNCTION_ARGS){ DateADT dateVal1 = PG_GETARG_DATEADT(0); DateADT dateVal2 = PG_GETARG_DATEADT(1); PG_RETURN_DATEADT((dateVal1 > dateVal2) ? dateVal1 : dateVal2);}Datumdate_smaller(PG_FUNCTION_ARGS){ DateADT dateVal1 = PG_GETARG_DATEADT(0); DateADT dateVal2 = PG_GETARG_DATEADT(1); PG_RETURN_DATEADT((dateVal1 < dateVal2) ? dateVal1 : dateVal2);}/* Compute difference between two dates in days. */Datumdate_mi(PG_FUNCTION_ARGS){ DateADT dateVal1 = PG_GETARG_DATEADT(0); DateADT dateVal2 = PG_GETARG_DATEADT(1); PG_RETURN_INT32((int32) (dateVal1 - dateVal2));}/* Add a number of days to a date, giving a new date. * Must handle both positive and negative numbers of days. */Datumdate_pli(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); int32 days = PG_GETARG_INT32(1); PG_RETURN_DATEADT(dateVal + days);}/* Subtract a number of days from a date, giving a new date. */Datumdate_mii(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); int32 days = PG_GETARG_INT32(1); PG_RETURN_DATEADT(dateVal - days);}/* * Internal routines for promoting date to timestamp and timestamp with * time zone */#ifdef HAVE_INT64_TIMESTAMP/* date is days since 2000, timestamp is microseconds since same... */#define date2timestamp(dateVal) \ ((Timestamp) ((dateVal) * USECS_PER_DAY))#else/* date is days since 2000, timestamp is seconds since same... */#define date2timestamp(dateVal) \ ((Timestamp) ((dateVal) * (double)SECS_PER_DAY))#endifstatic TimestampTzdate2timestamptz(DateADT dateVal){ TimestampTz result; struct pg_tm tt, *tm = &tt; int tz; j2date(dateVal + POSTGRES_EPOCH_JDATE, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday)); tm->tm_hour = 0; tm->tm_min = 0; tm->tm_sec = 0; tz = DetermineTimeZoneOffset(tm, global_timezone);#ifdef HAVE_INT64_TIMESTAMP result = dateVal * USECS_PER_DAY + tz * USECS_PER_SEC;#else result = dateVal * (double) SECS_PER_DAY + tz;#endif return result;}/* * Crosstype comparison functions for dates */Datumdate_eq_timestamp(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); Timestamp dt1; dt1 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);}Datumdate_ne_timestamp(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); Timestamp dt1; dt1 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);}Datumdate_lt_timestamp(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); Timestamp dt1; dt1 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);}Datumdate_gt_timestamp(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); Timestamp dt1; dt1 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);}Datumdate_le_timestamp(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); Timestamp dt1; dt1 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);}Datumdate_ge_timestamp(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); Timestamp dt1; dt1 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);}Datumdate_cmp_timestamp(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); Timestamp dt1; dt1 = date2timestamp(dateVal); PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));}Datumdate_eq_timestamptz(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) == 0);}Datumdate_ne_timestamptz(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) != 0);}Datumdate_lt_timestamptz(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) < 0);}Datumdate_gt_timestamptz(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) > 0);}Datumdate_le_timestamptz(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) <= 0);}Datumdate_ge_timestamptz(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) >= 0);}Datumdate_cmp_timestamptz(PG_FUNCTION_ARGS){ DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = date2timestamptz(dateVal); PG_RETURN_INT32(timestamptz_cmp_internal(dt1, dt2));}Datumtimestamp_eq_date(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); Timestamp dt2; dt2 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);}Datumtimestamp_ne_date(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); Timestamp dt2; dt2 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);}Datumtimestamp_lt_date(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); Timestamp dt2; dt2 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);}Datumtimestamp_gt_date(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); Timestamp dt2; dt2 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);}Datumtimestamp_le_date(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); Timestamp dt2; dt2 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);}Datumtimestamp_ge_date(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); Timestamp dt2; dt2 = date2timestamp(dateVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);}Datumtimestamp_cmp_date(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); Timestamp dt2; dt2 = date2timestamp(dateVal); PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));}Datumtimestamptz_eq_date(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); TimestampTz dt2; dt2 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) == 0);}Datumtimestamptz_ne_date(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); TimestampTz dt2; dt2 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) != 0);}Datumtimestamptz_lt_date(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); TimestampTz dt2; dt2 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) < 0);}Datumtimestamptz_gt_date(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); TimestampTz dt2; dt2 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) > 0);}Datumtimestamptz_le_date(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); TimestampTz dt2; dt2 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) <= 0);}Datumtimestamptz_ge_date(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); TimestampTz dt2; dt2 = date2timestamptz(dateVal); PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) >= 0);}Datumtimestamptz_cmp_date(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); TimestampTz dt2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -