Yii2 國(guó)際化之時(shí)區(qū)轉(zhuǎn)換


一、說(shuō)在前面

首先明白,應(yīng)用里有兩個(gè)地方可設(shè)置時(shí)區(qū),

一是application里的timezone,

這里的時(shí)區(qū)設(shè)置是整個(gè)應(yīng)用的時(shí)區(qū)設(shè)置,在Application.php源碼里可看到:它會(huì)作用于date函數(shù),


這里有這樣的一個(gè)場(chǎng)景:

A是UTC時(shí)區(qū)的用戶,他電腦上顯示的時(shí)間是上午12點(diǎn),他在Yii2(應(yīng)用時(shí)區(qū)設(shè)置是PRC)上創(chuàng)建的一條數(shù)據(jù),那這條記錄的created_at是什么時(shí)間?是的,created_at是PRC的時(shí)間,即晚上8點(diǎn)。因?yàn)閏reated_at是通過(guò)date函數(shù)生成。

二是formatter的defaultTimeZone和timeZone 屬性

使用formatter轉(zhuǎn)換時(shí)間時(shí),會(huì)先判斷這里的defaultTimeZone與formatter中的timezone的時(shí)間差,然后將轉(zhuǎn)換后的時(shí)間顯示出來(lái)。

時(shí)區(qū)轉(zhuǎn)換參考代碼:yii::$app->formatter->asDatetime($model['updated_at'],'full');

時(shí)區(qū)轉(zhuǎn)換:從defaultTimeZone時(shí)區(qū)轉(zhuǎn)到timezone時(shí)區(qū),因此,defaultTimeZone的值需與application中的timezone保持一致

(若formatter的timezone未指定,默認(rèn)取application的timezone,需要轉(zhuǎn)換時(shí)區(qū)顯示的時(shí)候,修改formatter的timezone即可)

這里是一個(gè)簡(jiǎn)單的例子:

formatter里的timezone是UTC

formatter的defaultTimeZone是PRC

數(shù)據(jù)庫(kù)有一條記錄時(shí)間值是

2019-04-04? 20:00:00

那在頁(yè)面上使用formatter轉(zhuǎn)換時(shí)間時(shí),顯示的時(shí)間是多少?

2019-04-04? 12:00:00

二、既然是國(guó)際化應(yīng)用,難免會(huì)有不同時(shí)區(qū)的用戶在使用同一個(gè)yii2應(yīng)用,這個(gè)時(shí)候,時(shí)間如何處理?

1、應(yīng)用時(shí)區(qū)設(shè)置:

application里的timezone是PRC

formatter里的timezone是PRC(目標(biāo)時(shí)區(qū))

formatter的defaultTimeZone是PRC

場(chǎng)景:UTC用戶和PRC用戶同時(shí)在Yii2上寫工作日志,能夠查看對(duì)方的記錄

數(shù)據(jù)庫(kù)有記錄時(shí)間兩個(gè)的字段:created_at和work_date

created_at是應(yīng)用通過(guò)date函數(shù)生成,work_date是用戶通過(guò)HTML界面日期組件選擇的,

因?yàn)椴煌瑫r(shí)區(qū)的用戶,終端電腦的時(shí)間是不一樣的,

假如UTC用戶選擇work_date為當(dāng)前時(shí)間:上午12點(diǎn),但實(shí)際上created_at字段入庫(kù)的時(shí)間是晚上8點(diǎn)(PRC)。那UTC的用戶就很尷尬了,明明現(xiàn)在只是中午12點(diǎn),看到這條記錄的創(chuàng)建時(shí)間卻是20點(diǎn),時(shí)間穿越了?


這里是解決的方案:

1、用戶必須選擇自己所在的時(shí)區(qū),

2、通過(guò)組件選擇的時(shí)間字段需全部轉(zhuǎn)換成PRC時(shí)間入庫(kù),也就是work_date入庫(kù)時(shí)間應(yīng)該為20點(diǎn)

3、保存后查看時(shí),將work_date和created_at通過(guò)formatter(defaultTimeZone是PRC,timezone是UTC)轉(zhuǎn)后顯示出來(lái)

? 都將顯示為上午12點(diǎn)。

總而言之:

1、formatter的defaultTimeZone必須與application的timezone保持一致,

2、只能通過(guò)修改formatter里的timezone來(lái)修改顯示的時(shí)區(qū)時(shí)間,

3、所有時(shí)間字段在入庫(kù)時(shí),必須保持與application->timezone的時(shí)區(qū)時(shí)間一致,

4、項(xiàng)目一旦部署,不要再修改application->timezone,更不能由用戶選擇時(shí)區(qū)而改變application->timezone。

5、application->timezone可以在common\config\main.php中設(shè)置,也可以在每個(gè)應(yīng)用中的config\main.php中設(shè)置

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容