1. 程式人生 > >postgres Date/Time 學習筆記

postgres Date/Time 學習筆記

一、Date/Time Types

Types 別名
timestamp [ (p) ] [ without time zone ]
timestamp [ (p) ] with time zone timestamptz
date
time [ (p) ] [ without time zone ]
time [ (p) ] with time zone
interval [ fields ] [ (p) ]

注:sequelize 裡常用的 DATE 型別指的是 postgres 的 timestamptz 型別

二、Date/Time Input / Output

前提:postgres 的時區設定成了 PRC(中國)。

1、普通值

例:2018-08-16 20:12:16+08

//存 
INSERT INTO "public"."MemberOrderLasts"("id","mobile","last_time")
VALUES
(1,'13600000000','2018-08-16 20:12:16+08');

//從庫取
select  "last_time"  from "MemberOrderLasts"  where id = '1'
//2018-08-16 20:12:16.920642+08

//直接取 
select timestamp '1999-01-08 04:05:06.789+08'
//1999-01-08 04:05:06.789 
select date '1999-01-08 04:05:06.789+08'
//1999-01-08 
select time '1999-01-08 04:05:06.789+08'
//04:05:06.789

注:即使輸入帶時區的時間戳,postgres 底層存的也是轉換後的 UTC 時間。通過 set timezone 可以改變了資料庫展示時間的方式(帶時區)

2、特殊值

當在 SQL 命令中用作常量時,所有這些值都需要用單引號括起來。

Input String Valid Types Description
epoch date, timestamp 1970-01-01 00:00:00+00 (Unix system time zero)
infinity date, timestamp later than all other time stamps
-infinity date, timestamp earlier than all other time stamps
now date, time, timestamp current transaction's start time
today date, timestamp midnight today
tomorrow date, timestamp midnight tomorrow
yesterday date, timestamp midnight yesterday
allballs time 00:00:00.00 UTC
//存 
INSERT INTO "public"."MemberOrderLasts"("id","mobile","last_time")
VALUES
(2,'13600000000','now');

//從庫取
select  "last_time"  from "MemberOrderLasts"  where id = '2'
//2018-09-13 14:15:12.920642+08

//直接取 
select timestamp 'now'
//2018-09-13 14:29:42.27933 

三、Date/Time TimeZone

1、配置檔案

postgresql.conf

timezone = 'PRC'

2、postgres CLI

set timezone = 'xxx'

注意:推薦時區用 PRCAsia/Shanghai 而不是 +08:00

因為時區和時區慣例受政治決策的影響,而不僅僅是地球幾何。世界各地的時區在 20 世紀初變得有些標準化,但仍然容易發生任意變化。

四、Date/Time Functions and Operators

1、運算子

+ / -* / / 不贅述,具體看文件)

select date '2018-01-12' + interval '7'
-- 2018-01-12 00:00:07 

select "activatedAt" - "createdAt" AS "diff" from "Members" where id = '373' 
-- 19 days 09:07:11.155

2、函式

Function Return Type Description Example Result
age( timestamp , timestamp ) interval Subtract arguments, producing a "symbolic" result that uses years and months age(timestamp '2001-04-10', timestamp '1957-06-13') 43 years 9 mons 27 days
age( timestamp ) interval Subtract from current_date (at midnight) age(timestamp '1957-06-13') 43 years 8 mons 3 days
date_part( text , timestamp ) double precision Get subfield (equivalent to extract); see Section 9.9.1 date_part('hour', timestamp '2001-02-16 20:38:40') 20
date_part( text , interval ) double precision Get subfield (equivalent to extract); see Section 9.9.1 date_part('month', interval '2 years 3 months') 3
date_trunc( text , timestamp ) timestamp Truncate to specified precision; see also Section 9.9.2 date_trunc('hour', timestamp '2001-02-16 20:38:40') 2001-02-16 20:00:00
extract(field from timestamp ) double precision extract(hour from timestamp '2001-02-16 20:38:40') 20
extract(field from interval ) double precision extract(month from interval '2 years 3 months') 3
isfinite( date ) boolean Test for finite date (not +/-infinity) isfinite(date '2001-02-16') true
isfinite( timestamp ) boolean Test for finite time stamp (not +/-infinity) isfinite(timestamp '2001-02-16 21:28:30') true
isfinite( interval ) boolean Test for finite interval isfinite(interval '4 hours') true
justify_days( interval ) interval Adjust interval so 30-day time periods are represented as months justify_days(interval '35 days') 1 mon 5 days
justify_hours( interval ) interval Adjust interval so 24-hour time periods are represented as days justify_hours(interval '27 hours') 1 day 03:00:00
justify_interval( interval ) interval Adjust interval using justify_days and justify_hours, with additional sign adjustments justify_interval(interval '1 mon -1 hour') 29 days 23:00:00

3、查詢時間是否重疊

(start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2)

// `(start1, end1) OVERLAPS (start2, end2)`
SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS
       (DATE '2001-10-30', DATE '2002-10-30');
Result: true

// `(start1, length1) OVERLAPS (start2, length2)`
SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS
       (DATE '2001-10-30', DATE '2002-10-30');
Result: false

// 遵循左開右閉的原則
SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS
       (DATE '2001-10-30', DATE '2001-10-31');
Result: false
SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS
       (DATE '2001-10-30', DATE '2001-10-31');
Result: true

五、Current Date/Time

1、普通專用

(1)帶時區資訊

CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP CURRENT_TIME(precision) CURRENT_TIMESTAMP(precision)

(2)不帶時區資訊

LOCALTIME LOCALTIMESTAMP LOCALTIME(precision) LOCALTIMESTAMP(precision)

select CURRENT_TIMESTAMP
// 2018-09-13 15:10:05.639902+08
select LOCALTIMESTAMP  
// 2018-09-13 15:10:05.639902

還記得上面說的特殊值 now 嗎,實際上跟 CURRENT_TIMESTAMP 一樣:

//下面三個完全相等
SELECT CURRENT_TIMESTAMP;
SELECT TIMESTAMP 'now';
SELECT now();

2、事務專用

為了保障同一事務中的多個修改具有相同的時間戳,所以 postgre 提供了針對性的時間函式:

(1) transaction_timestamp() 返回事務開始的時間

(2) statement_timestamp() 返回當前語句的開始時間

statement_timestamp() 和 transaction_timestamp() 只在一個事務的第一條命令裡返回值相同

(3) clock_timestamp() 返回實際的當前時間,因此即使在單個 SQL 命令中它的值也會更改

六、Delaying Execution

pg_sleep()讓當前的會話程序休眠 seconds 秒以後再執行。

SELECT pg_sleep(1.5);