postgres Date/Time 學習筆記

1、Date/Time Types


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

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 類型sql

2、Date/Time Input / Output


前提:postgres 的時區設置成了 PRC(中國)。數據庫

一、普通值

例: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 能夠改變了數據庫展現時間的方式(帶時區)post

二、特殊值

當在 SQL 命令中用做常量時,全部這些值都須要用單引號括起來。ui

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

3、Date/Time TimeZone


一、配置文件

postgresql.confpostgresql

timezone = 'PRC'code

二、postgres CLI

set timezone = 'xxx'htm

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

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

4、Date/Time Functions and Operators


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

一、運算符

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

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

二、函數

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

三、查詢時間是否重疊

(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

5、Current Date/Time


一、普通專用

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

二、事務專用

爲了保障同一事務中的多個修改具備相同的時間戳,因此 postgre 提供了針對性的時間函數:

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

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

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

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

6、Delaying Execution


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

SELECT pg_sleep(1.5);
相關文章
相關標籤/搜索