PostgreSQL 支持 SQL标准中所有的日期和时间类型
日期/时间类型
名字 | 描述 |
timestamp [ (p) ] [ without time zone ] | 日期和时间(无时区) |
timestamp [ (p) ] with time zone | 日期和时间,有时区 |
date | 只用于日期 |
time [ (p) ] [ without time zone ] | 只用于一日内时间 |
time [ (p) ] with time zone | 只用于一日内时间,带时区 |
interval [ fields ] [ (p) ] | 时间间隔 |
date 类型定义,整型,date的输入输出函数使它表示成‘yyyy-mm-dd’,后面介绍这些函数
typedef int32 DateADT;
time 类型定义,时间部分是整型。TimeTzADT 结构体是时区
#ifdef HAVE_INT64_TIMESTAMP
typedef int64 TimeADT;
#else
typedef float8 TimeADT;
#endif
typedef struct
{
TimeADT time; /* all time units other than months and years */
int32 zone; /* numeric time zone, in seconds */
} TimeTzADT;
PostgreSQL 使用儒略历法(Julian dates)来进行所有的日期/时间计算。(儒略日、朱莉安不同译法而已)
解释一下朱莉安日历(Julian date):
174表示的是从2016年1月1日开始到今天已有174天了
普通日历是按月计数,朱莉安日历是按年计数
datetime.h
Definitions for date/time support code.
src/include/utils/datetime.h
声明了 date,Julian date 转换的相关函数
/* 朱莉安日期转换日历时间 */
extern void j2date(int jd, int *year, int *month, int *day);
/* 日历时间与朱莉安日历的转换 */
extern int date2j(int year, int month, int day);
/* 朱莉安日期转换为星期几 */
extern int j2day(int jd);
date.h
Definitions for the SQL "date" and "time" types.
src/include/utils/date.h
Datum、date、time 类型的转换以及输入输出函数,上面的将 typedef int32 DateADT 输出“yyyy-mm-dd”
/*
* Macros for fmgr-callable functions.
*
* For TimeADT, we make use of the same support routines as for float8 or int64.
* Therefore TimeADT is pass-by-reference if and only if float8 or int64 is!
*/
#ifdef HAVE_INT64_TIMESTAMP
#define MAX_TIME_PRECISION 6
#define DatumGetDateADT(X) ((DateADT) DatumGetInt32(X))
#define DatumGetTimeADT(X) ((TimeADT) DatumGetInt64(X))
#define DatumGetTimeTzADTP(X) ((TimeTzADT *) DatumGetPointer(X))
#define DateADTGetDatum(X) Int32GetDatum(X)
#define TimeADTGetDatum(X) Int64GetDatum(X)
#define TimeTzADTPGetDatum(X) PointerGetDatum(X)
#else /* !HAVE_INT64_TIMESTAMP */
#define MAX_TIME_PRECISION 10
/* round off to MAX_TIME_PRECISION decimal places */
#define TIME_PREC_INV 10000000000.0
#define TIMEROUND(j) (rint(((double) (j)) * TIME_PREC_INV) / TIME_PREC_INV)
#define DatumGetDateADT(X) ((DateADT) DatumGetInt32(X))
#define DatumGetTimeADT(X) ((TimeADT) DatumGetFloat8(X))
#define DatumGetTimeTzADTP(X) ((TimeTzADT *) DatumGetPointer(X))
#define DateADTGetDatum(X) Int32GetDatum(X)
#define TimeADTGetDatum(X) Float8GetDatum(X)
#define TimeTzADTPGetDatum(X) PointerGetDatum(X)
#endif /* HAVE_INT64_TIMESTAMP */
#define PG_GETARG_DATEADT(n) DatumGetDateADT(PG_GETARG_DATUM(n))
#define PG_GETARG_TIMEADT(n) DatumGetTimeADT(PG_GETARG_DATUM(n))
#define PG_GETARG_TIMETZADT_P(n) DatumGetTimeTzADTP(PG_GETARG_DATUM(n))
#define PG_RETURN_DATEADT(x) return DateADTGetDatum(x)
#define PG_RETURN_TIMEADT(x) return TimeADTGetDatum(x)
#define PG_RETURN_TIMETZADT_P(x) return TimeTzADTPGetDatum(x)
日期/时间类型转换的相关函数,下面只介绍几个类型转换的函数,不一一列举
extern Datum date_timestamp(PG_FUNCTION_ARGS);
extern Datum timestamp_date(PG_FUNCTION_ARGS);
extern Datum date_timestamptz(PG_FUNCTION_ARGS);
extern Datum timestamptz_date(PG_FUNCTION_ARGS);
extern Datum datetime_timestamp(PG_FUNCTION_ARGS);
extern Datum timestamp_time(PG_FUNCTION_ARGS);
extern Datum timestamptz_time(PG_FUNCTION_ARGS);
extern Datum time_interval(PG_FUNCTION_ARGS);
extern Datum interval_time(PG_FUNCTION_ARGS);
timestamp、timestametz 可由 date 类型转换而来。
pgtime.h
PostgreSQL internal timezone library
src/include/pgtime.h
声明了pg_tm 结构体
struct pg_tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday; /* 1..31 */
int tm_mon; /* origin 0, not 1 */
int tm_year; /* relative to 1900 */
int tm_wday; /* 0..6 (0是周一)*/
int tm_yday; /* 1..366 Julian date */
int tm_isdst;
long int tm_gmtoff;
const char *tm_zone;
};
timestamp.h
Definitions for the SQL "timestamp" and "interval" types.
src/include/utils/timestamp.h
声明了timestamp interval 类型相关的函数,这里介绍下 pg_tm 结构体跟 timestamp 的转换函数,后面介绍 pg_tm
extern int tm2timestamp(struct pg_tm * tm, fsec_t fsec, int *tzp, Timestamp *dt);
extern int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm * tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone);