postgres Date/Time 學習筆記


一、Date/Time Types


參考文檔:https://www.postgresql.org/docs/9.2/static/datatype-datetime.html

Types 別名 備注
timestamp [ (p) ] [ without time zone ] 日期+時間
timestamp [ (p) ] with time zone timestamptz 日期+時間
date 日期
time [ (p) ] [ without time zone ] 時間
time [ (p) ] with time zone timetz 時間
interval [ fields ] [ (p) ] 時間段

注:

1、sequelize 里常用的 DATE 類型指的是 postgres 的 timestamptz 類型

2、僅 Date 沒有時區概念。

3、interval 這里不展開了,待寫。

二、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
 

注:對於國內程序員來說,使用“/”容易產生歧義,最好使用“-”做分隔,即 2018-08-16 20:12:16

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');

三、Date/Time TimeZone


參考我另一篇:《從 moment -> nodejs -> sequelize -> postgres,你都得設置好時區》

四、Date/Time Functions and Operators


參考文檔:https://www.postgresql.org/docs/9.2/static/functions-datetime.html

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 Get subfield; see Section 9.9.1 extract(hour from timestamp '2001-02-16 20:38:40') 20
extract(field from interval ) double precision Get subfield; see Section 9.9.1 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
常用:extract / date_part 和 date_trunc 函數
1、extract / date_part
select date_part('hour', timestamp '2001-02-16 20:38:40')
-- 20
select extract('hour' from timestamp '2001-02-16 20:38:40')
-- 20

2、date_trunc
select date_trunc('hour', timestamp '2001-02-16 20:38:40')
-- 2001-02-16 20:00:00

3、查詢時間是否重疊

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

// 一、兩種用法
// 1、`(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

// 2、`(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、普通

注意:下面的日期/時間在同一個事務里都是不變的。(如果要變化,建議使用下面即將介紹的 statement_timestamp 或者 clock_timestamp )。

(1)帶時區信息

CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TIME(precision)
CURRENT_TIMESTAMP(precision)


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

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

(2)不帶時區信息

LOCALTIME
LOCALTIMESTAMP
LOCALTIME(precision)
LOCALTIMESTAMP(precision)

僅 Date 沒有時區概念。

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

2、事務專用

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

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

其實 transaction_timestamp = CURRENT_TIMESTAMP ,只是針對的場景不同,所以換了個名字。

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

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

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

select clock_timestamp(),clock_timestamp()
-- 2020-03-05 16:59:04.264526+08 | 2020-03-05 16:59:04.264527+08 (不一樣)

六、Delaying Execution


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

SELECT pg_sleep(1.5);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM