搭建兩個虛擬環境,操做系統均是cents7。java
環境A:python
使用timedatectl命令查看時區爲 Time zone: Asia/Shanghai (CST, +0800)。mysql
本地數據庫時區(show timezone命令)爲PRC,等價於cst。sql
環境B:數據庫
時區爲America/New_York (EST, -0500),本地數據庫時區爲US/Eastern,等價於EST。函數
1. 先針對timestamp with time zone和timestamp without time zone兩個配置進行測試。工具
在環境A的數據庫創建數據表並寫入數據:post
CREAT TABLE test_timestamp( ttz timestamp with time zone, twtz timestamp without time zone );
INSERT INTO test_timestamp VALUES (now(),now());
查看數據:測試
postgres=# table test_timestamp; ttz | twtz -------------------------------+---------------------------- 2019-02-15 11:28:26.994804+08 | 2019-02-15 11:28:26.994804 (1 row)
在環境B中,使用python查看:spa
>>> data = pd.read_sql(''' select * from test_timestamp ''', conn) >>> data ttz twtz 0 2019-02-15 03:28:26.994804+00:00 2019-02-15 11:28:26.994804 >>>
會發現ttz字段自動轉換成了UTC時間,而twtz字段原封不動的輸出。
再測試環境B寫入數據:
本地時間爲:$ date Thu Feb 14 22:33:42 EST 2019 執行cur.execute(''' insert into test_timestamp values('2019-02-14 22:33:42','2019-02-14 22:33:42') ''')
在A的數據庫中查看:
postgres=# table test_timestamp; ttz | twtz -------------------------------+---------------------------- 2019-02-15 11:28:26.994804+08 | 2019-02-15 11:28:26.994804 2019-02-14 22:33:42+08 | 2019-02-14 22:33:42 (2 rows)
發現ttz字段日期值加上了環境A的時區,出現了誤差。由於插入語句用的是字符串類型,是的數據庫默認爲本地時區。
寫入數據時若是調用sql函數:
cur.execute(''' insert into test_timestamp values(now(),now()) ''')
在環境A中:
postgres=# table test_timestamp; ttz | twtz -------------------------------+---------------------------- 2019-02-15 11:28:26.994804+08 | 2019-02-15 11:28:26.994804 2019-02-14 22:33:42+08 | 2019-02-14 22:33:42 2019-02-15 11:41:13.080922+08 | 2019-02-15 11:41:13.080922 (3 rows)
插入的也是環境A的本地時間。也就是說,最後都是以數據庫的環境來執行。
結論:
A. 同一時區內,沒有差異。跨時區時,若是隻是跨時區讀(寫操做由一個特定時區完成),能夠當作是無差異,都須要轉換一下,設置成with time zone可能會好一些,由於在讀取的時候有些工具或語言(好比java)會自動轉成當地時區的時間。若是是跨時區寫,那麼就要設置成without time zone,要否則數據庫記錄的時間會有錯誤,由於寫的時候傳的是字符串,數據庫會加上本地時區。
B. 不一樣數據庫時間類型的名稱不同,postgres裏面沒有datetime類型,用timestamp表示datetime;在mysql裏有datetime類型,也有timestamp類型(含義和postgres裏面不同)。表示的範圍大小、是否是帶有時區信息也要查看具體數據庫的手冊。
C. postgres日期類型通常都是「YYYY-MM-DD HH:mm:ss」格式,不接受通常理解上的數字類型的時間戳(int型數值)的輸入。時間類型(好比updatetime和tradedate等)的設置不必定得是數值格式,也能夠是日期格式,只是須要注意好時區問題。