數據庫中日期、時間、時間戳的問題(未完待續)
最近在Postgresql中導入數據,遇到時間問題,將數據庫中的時間進行梳理下:
1.基本概念
1.1 日期(date):也就是常說的年、月、日,以下為合法的日期格式列表:
例子 | 描述 |
January 8, 1999 | 在任何datestyle輸入模式下都無歧義 |
1999-01-08 | ISO-8601格式,任何方式下都是1999年1月8號,(建議格式) |
1/8/1999 | 歧義,在MDY下是1月8號;在 DMY模式下讀做8月1日 |
1/18/1999 | 在MDY模式下讀做1月18日,其它模式下被拒絕 |
01/02/03 | MDY模式下的2003年1月2日;DMY模式下的2003年2月1日;YMD 模式下的2001年2月3日 |
1999-Jan-08 | 任何模式下都是1月8日 |
Jan-08-1999 | 任何模式下都是1月8日 |
08-Jan-1999 | 任何模式下都是1月8日 |
99-Jan-08 | 在YMD模式下是1月8日,否則錯誤 |
08-Jan-99 | 1月8日,除了在YMD模式下是錯誤的之外 |
Jan-08-99 | 1月8日,除了在YMD模式下是錯誤的之外 |
19990108 | ISO-8601; 任何模式下都是1999年1月8日 |
990108 | ISO-8601; 任何模式下都是1999年1月8日 |
1.2 時間(time):一天中的時刻,使用時、分、秒表示,其後面可以帶有可選的時區,以下為合法的時間格式列表:
例子 | 描述 |
04:05:06.789 | ISO 8601 |
04:05:06 | ISO 8601 |
04:05 | ISO 8601 |
040506 | ISO 8601 |
04:05 AM | 與04:05一樣;AM不影響數值 |
04:05 PM | 與16:05一樣;輸入小時數必須 <= 12 |
04:05:06.789-8 | ISO 8601 |
04:05:06-08:00 | ISO 8601 |
04:05-08:00 | ISO 8601 |
040506-08 | ISO 8601 |
04:05:06 PST | 帶縮寫的時區 |
2003-04-12 04:05:06 America/New_York | 帶全稱的時區 |
1.3 時間戳(timestamp):
(1)1999-01-08 04:05:06
(2)1999-01-08 04:05:06 -8:00
1.4 時區:
例子 | 描述 |
PST | 太平洋標準時間(Pacific Standard Time) |
America/New_York | 時區全稱 |
PST8PDT | POSIX風格的時區名稱 |
-8:00 | ISO-8601 與 PST 的偏移 |
-800 | ISO-8601 與 PST 的偏移 |
-8 | ISO-8601 與 PST 的偏移 |
Zulu | 軍方對 UTC 的縮寫(譯註:可能是美軍) |
Z | Zulu的縮寫 |
關於時區需要註意的問題:
(1)SQL標準通過查看符號"+" 或 "-" 是否存在來區分常量的類型是 timestamp without time zone還是timestamp with time zone。 例如,TIMESTAMP ‘2004-10-19 10:23:54‘的類型timestamp without time zone,TIMESTAMP ‘2004-10-19 10:23:54+02‘的類型是timestamp with time zone。PostgreSQL不使用這個規則,因此前面的兩個例子的例子都會被認為timestamp without time zone。在PostgreSQL中,timestamp without time zone類型的常量前面必須加上TIMESTAMP WITH TIME ZONE, 例如,TIMESTAMP WITH TIME ZONE ‘2004-10-19 10:23:54+02‘。
(2)timestamp without time zone類型的常量中如果有時區信息,時區信息會被系統自動忽略。
(3)timestamp with time zone類型的數據的內部存儲的格式總是UTC(全球統一時間,以前也叫格林威治時間GMT)。如果一個輸入值中指定了時區,系統將以該時區為依據將它轉換為UTC格式,如果在輸入的值中沒有指定聲明,系統以參數timezone的值作為指定時區為依據,將它轉換為UTC格式。
(4)如果要輸出一個 timestamp with time zone類型的數據,它總是從 UTC被轉到參數timezone指定的時區,並被顯示為該時區的本地時間。 要看其它時區的該時間,要麽修改 參數參數timezone的值,要麽使用 AT TIME ZONE 子句。
(5)在 timestamp without time zone 和 timestamp with time zone 之間的進行轉換是通常假設 timestamp without time zone 數值的時區是參數timezone 指定的時區。可以用AT TIME ZONE 指定其它的時區。
1.5 時間間隔(interval):(註:此部分理解還不是很好,有待完善)
interval類型的數值可以用下面語法來定義:
[@] quantity unit [quantity unit...] [direction]
這裏quantity 是一個數字(可能有符號),unit 是 microsecond、 millisecond、second、minute,、hour、day、 week、month、year、decade、century、millennium或者這些單位的縮寫或復數,direction 可以是 ago 或者為空。符號 “@” 是可選的,可以不寫。
天、小時、分鐘以及秒的數值的後面可以不用明確地跟單位。 比如,“1 12:59:10” 和 “1 day 12 hours 59 min 10 sec”是等價的。可選精度 p 的取值在0到6 之間,默認是輸入的常量的精度。
2 PostgreSQL 中支持的日期/時間類型
PostgreSQL 支持 SQL標準中所有的日期和時間類型,如下所示:
名稱 | 存儲空間大小 | 描述 | 最小值 | 最大值 | 分辨率 |
date | 4 bytes | 只有日期 | 4713 BC(公元前4713) | 5874897 AD(公歷紀元) | 1天 |
time [ (p) ] [ without time zone ] | 8 bytes | 只有時間 | 00:00:00 | 24:00:00 | 1微秒/14位 |
time [ (p) ] with time zone | 12 bytes | 只有時間,帶時區 | 00:00:00+1459 | 24:00:00-1459 | 1微秒/14位 |
timestamp [ (p) ] [ without time zone ] | 8 bytes | 包括日期和時間 | 4713 BC | 294276 AD | 1微秒/14位 |
timestamp [ (p) ] with time zone | 8 bytes | 包括日期和時間,帶時區 | 4713 BC | 294276 AD | 1微秒/14位 |
interval [ (p) ] | 12 bytes | 時間間隔 | -178000000 年 | 178000000 年 | 1微秒/14位 |
參考資料:
https://www.cnblogs.com/IamThat/p/5111168.html
https://www.cnblogs.com/stephen-liu74/archive/2012/04/30/2293602.html
https://www.postgresql.org/docs/current/static/datatype-datetime.html
數據庫中日期、時間、時間戳的問題(未完待續)