JDBC URL 時區設置問題
這篇主要是想要紀錄一下,最近發現的時區設置問題。
我在使用 Java 中的 new Date()
時,寫入 DB 的時間中發現少了時區,也就是少了 8 小時。
Quick Start
我的處理方式:
- 先檢查 Java 程式是否有處理時區,發現是用系統的時區。
- 再來檢查 DB Server 的時區,發現不正確後調整。
- DB 時區調整後,還是有一樣的問題,最後才發現是
JDBC URL
語法問題。
1. Docker 中的時區
我是使用 Docker
來啟動我的 mysql
的。1
$ docker run -p 3306:3306 -d -e MYSQL_ROOT_PASSWORD=root --name=mysql mysql:5.7
由於一開始沒有設定時區,因此我是進入到 container
調整我的時區的。
進入
container
1
$ docker exec -it mysql sh
我們可先使用
date
指令確認一下目前系統時間1
date
使用
tzselect
指令調整時區,執行過程請參考下方:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56# tzselect
Please identify a location so that time zone rules can be set correctly.
Please select a continent, ocean, "coord", or "TZ".
1) Africa
2) Americas
3) Antarctica
4) Asia
5) Atlantic Ocean
6) Australia
7) Europe
8) Indian Ocean
9) Pacific Ocean
10) coord - I want to use geographical coordinates.
11) TZ - I want to specify the time zone using the Posix TZ format.
#? 4
Please select a country whose clocks agree with yours.
1) Afghanistan 18) Israel 35) Palestine
2) Armenia 19) Japan 36) Philippines
3) Azerbaijan 20) Jordan 37) Qatar
4) Bahrain 21) Kazakhstan 38) Russia
5) Bangladesh 22) Korea (North) 39) Saudi Arabia
6) Bhutan 23) Korea (South) 40) Singapore
7) Brunei 24) Kuwait 41) Sri Lanka
8) Cambodia 25) Kyrgyzstan 42) Syria
9) China 26) Laos 43) Taiwan
10) Cyprus 27) Lebanon 44) Tajikistan
11) East Timor 28) Macau 45) Thailand
12) Georgia 29) Malaysia 46) Turkmenistan
13) Hong Kong 30) Mongolia 47) United Arab Emirates
14) India 31) Myanmar (Burma) 48) Uzbekistan
15) Indonesia 32) Nepal 49) Vietnam
16) Iran 33) Oman 50) Yemen
17) Iraq 34) Pakistan
#? 43
The following information has been given:
Taiwan
Therefore TZ='Asia/Taipei' will be used.
Local time is now: Thu Aug 15 17:14:10 CST 2019.
Universal Time is now: Thu Aug 15 09:14:10 UTC 2019.
Is the above information OK?
1) Yes
2) No
#? Yes
Please enter a number in range.
#? 1
You can make this change permanent for yourself by appending the line
TZ='Asia/Taipei'; export TZ
to the file '.profile' in your home directory; then log out and log in again.
Here is that TZ value again, this time on standard output so that you
can use the /usr/bin/tzselect command in shell scripts:
Asia/Taipei複製時區至
/etc/localtime
1
cp /usr/share/zoneinfo/Asia/Taipei /etc/localtime
更新時間
1
ntpdate time.windows.com
離開
container
後restart
1
docker restart mysql
JDBC 連線 URL 設定
- 透過 DB Client 驗證時間是否正確,可使用
select now();
語法。 - 確認正確後,但是使用 Java 寫法中的
new Date()
時,寫入 DB 的時間還是不正確,少了時區。
後來上網找資料才發現,我使用到了新版本的 mysql driver : mysql-connector-java:8.0.16
新版本的 JDBC URL
需要增加 serverTimezone
,調整如下:1
jdbc:mysql://localhost:3306/gp_lotcenter?serverTimezone=Asia/Taipei
補充說明
在使用 Docker
啟動 mysql
時,可以一開始就帶入本地端的時間配置給 container
,如:1
2
3
4
5$ docker run -p 3306:3306 -d \
-e MYSQL_ROOT_PASSWORD=root \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
--name=mysql mysql:5.7
這樣就不用特地進入 container
裡面調整時區了。
今天先到這邊了,如果有其他問題,歡迎寄信討論!謝謝!
Donate
謝謝您的支持與鼓勵