十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
docker中的mysql時區(qū)是使用了世界標準時間(UTC),把時區(qū)改成東八區(qū)方法:

創(chuàng)新互聯(lián)科技有限公司專業(yè)互聯(lián)網(wǎng)基礎服務商,為您提供BGP機房服務器托管,高防物理服務器租用,成都IDC機房托管,成都主機托管等互聯(lián)網(wǎng)服務。
1、啟動容器時設置: 添加如下配置:
2、進入docker配置:(重啟才能生效--永久生效)
3、臨時修改(從mysql上修改,重啟失效)
你還在被以下問題困擾嗎:
MySQL的安裝規(guī)范中應該設置什么時區(qū)?
JAVA應用讀取到的時間和北京時間差了14個小時,為什么?怎么解決?
已經(jīng)運行一段時間的業(yè)務,修改MySQL的時區(qū)會影響已經(jīng)存儲的時間類型數(shù)據(jù)嗎?
遷移數(shù)據(jù)時會有導致時間類型數(shù)據(jù)時區(qū)錯誤的可能嗎?
...
看完這篇文章,你能解決上面所有的疑惑。首先出場的是和時區(qū)相關的啟動參數(shù)和系統(tǒng)變量。
如果要在 MySQL 啟動時就指定時區(qū),則應該使用啟動參數(shù): default-time-zone ,示例:
啟動后我們可以看到控制時區(qū)的系統(tǒng)變量,其中 time_zone 變量控制時區(qū),在MySQL運行時可以通過 set 命令修改(注意:不可以寫在 my.cnf 中):
啟動參數(shù)和系統(tǒng)變量的可用值遵循相同的格式:
system_time_zone 變量只有全局值沒有會話值,不能動態(tài)修改,MySQL 啟動時,將嘗試自動確定服務器的時區(qū),并使用它來設置 system_time_zone 系統(tǒng)變量, 此后該值不變。當 time_zone='system' 時,就是使用的這個時區(qū),示例中 time_zone 就是 CST,而 CST 在 RedHat 上就是東八區(qū):
概括一下就兩點:
不僅是select now(),包括insert .. values(now())、以及字段的 DEFAULT CURRENT_TIMESTAMP 屬性也受此影響:
timestamp 數(shù)據(jù)類型會存儲當時session的時區(qū)信息,讀取時會根據(jù)當前 session 的時區(qū)進行轉(zhuǎn)換;而 datetime 數(shù)據(jù)類型插入的是什么值,再讀取就是什么值,不受時區(qū)影響。也可以理解為已經(jīng)存儲的數(shù)據(jù)是不會變的,只是 timestamp 類型數(shù)據(jù)在讀取時會根據(jù)時區(qū)轉(zhuǎn)換:
關于時區(qū)所有明面上的東西都在上面了,我們前面提到的困擾就是在暗處的經(jīng)驗。
1. MySQL的安裝規(guī)范中應該設置什么時區(qū)?
對于國內(nèi)的業(yè)務了,在 my.cnf 寫入 default-time-zone='+08:00' ,其他地區(qū)和開發(fā)確認取對應時區(qū)即可。
為什么不設置為 system 呢?使用系統(tǒng)時間看起來也是個不錯的選擇,比較省事。不建議的原因有兩點:
2. JAVA應用讀取到的時間和北京時間差了14個小時,為什么?怎么解決?
這通常是 JDBC 參數(shù)中沒有為連接設置時區(qū)屬性(用 serverTimezone 參數(shù)指定),并且MySQL中沒有設置全局時區(qū),這樣MySQL默認使用的是系統(tǒng)時區(qū),即 CST。這樣一來應用與MySQL 建立的連接的 session time_zone 為 CST ,前面我們提到 CST 在 RedHat 上是 +08:00 時區(qū),但其實它一共能代表4個時區(qū):
JDBC在解析CST時使用了美國標準時間,這就會導致時區(qū)錯誤。要解決也簡單:一是遵守上面剛說到的規(guī)范,對MySQL顯式地設置'+08:00'時區(qū);二是JDBC設置正確的 serverTimezone。
3. 已經(jīng)運行一段時間的業(yè)務,修改MySQL的時區(qū)會影響已經(jīng)存儲的時間類型數(shù)據(jù)嗎?
完全不會,只會影響對 timestamp 數(shù)據(jù)類型的讀取。這里不得不提一句,為啥要用 timestamp?用 datetime 不香嗎,范圍更大,存儲空間其實差別很小,趕緊加到開發(fā)規(guī)范中吧。
4. 遷移數(shù)據(jù)時會有導致時間類型數(shù)據(jù)時區(qū)錯誤的可能嗎?
這個還真有。
如何避免?mysqldump 也提供了一個參數(shù) --skip-tz-utc ,意思就是導出數(shù)據(jù)的那個連接不設置 UTC 時區(qū),使用 MySQL 的 global time_zone 系統(tǒng)變量值。
其實 mysqldump 導出 sql 文件時默認也是使用 UTC 時區(qū),并且會在導出的 sql 文件頭部帶有 session time_zone 信息,這樣可以保證導 SQL 文件導入和導出時使用相同的時區(qū),從而保證數(shù)據(jù)的時區(qū)正確(而導出的 csv 文件顯然不可以攜帶此信息)。需要注意的是 --compact 參數(shù)會去掉 sql 文件的所有頭信息,所以一定要記得: --compact 參數(shù)得和 --skip-tz-utc 一起使用。
1、查看當前時區(qū)
date -R
1
1
2、修改設置時區(qū)。先輸入 tzselect 命令,然后根據(jù)提示,通過輸入選項前面的數(shù)字來確定選項。我的例子,先選擇 Asia ,再選擇 Hong Kong。香港和中國采用了同樣的東八區(qū)時間。
3、復制相應的時區(qū)文件,替換原來的時區(qū)文件。命令如下:
/usr/share/zoneinfo/Asia# cp Hong_Kong /etc/localtime
1
1
我們需要的時區(qū)文件在目錄 /usr/share/zoneinfo/Asia 下。文件名字是 Hong_Kong。把它拷貝覆蓋 /etc/localtime 文件。
4、重新輸入命令 date -R,就可以看到修改時區(qū)后的中國時間了。
MySQL 時區(qū)默認是服務器的時區(qū)。
查看:
復制代碼代碼如下:
mysql SHOW VARIABLES LIKE '%time_zone%';
+------------------+--------+
| Variable_name| Value |
+------------------+--------+
| system_time_zone | CST|
| time_zone| SYSTEM |
+------------------+--------+
2 rows IN SET (0.00 sec)
可以通過修改my.cnf, 在 [mysqld] 之下加來修改時區(qū)。
default-time-zone=timezone
例如:
default-time-zone='+8:00'
修改后記得重啟msyql。
注意一定要在 [mysqld] 之下加 ,否則會出現(xiàn)錯誤: unknown variable ‘default-time-zone=+8:00′
另外也可以通過命令:
SET time_zone=timezone
例如:比如北京時間(GMT+0800)
SET time_zone='+8:00'
這個和php的時區(qū)設置又有點差別,比如北京時間在php中是:
date_default_timezone_set('Etc/GMT-8');
美國pst時間(GMT-08:00)
SET time_zone = '-8:00';
復制代碼代碼如下:
mysql SET time_zone = '+8:00';
Query OK, 0 rows affected (0.00 sec)
mysql SELECT now();
+---------------------+
| now() |
+---------------------+
| 2008-12-29 11:26:36 |
+---------------------+
1 row IN SET (0.00 sec)
mysql SET time_zone = '-8:00';
Query OK, 0 rows affected (0.00 sec)
mysql SELECT now();
+---------------------+
| now() |
+---------------------+
| 2008-12-28 19:27:09 |
+---------------------+
1 row IN SET (0.00 sec)
目前你遇到的問題大概是 PHP 獲取的時間和 MySQL中獲取的時間存在時差
比較直接的解決方案是在 PHP 和 MySQL 中遵循同一時區(qū)約定
PHP 在5.0 之后應該可以直接在代碼中設定時區(qū)
date_default_timezone_set('PRC');
MySQL 也可以通過修改配置文件 my.ini 或者 my.cnf 確保時區(qū)正確
default-time-zone=timezone
問題是你的MySQL服務器可能是在某臺美國服務器上租借的,沒法修改
所以解決的方法只能是:
修改插件源代碼,將 SQL 語句改為
select forum_id, count(post_id) todayposts
from ' .POSTS_TABLE. '
where date(from_unixtime(post_time)) = date(DATE_ADD(now(), INTERVAL 14 HOUR))
group by forum_id
其中的 DATE_ADD(now(), INTERVAL 14 HOUR) 是-14 還是 14,這需要你仔細考慮下