JVM默認(rèn)時(shí)區(qū)為:Asia/Shanghai與java程序中GMT+08不一致異常
在Spring程序中配置了spring.jackson.time-zone=GMT+08時(shí),部分時(shí)間相差一個(gè)小時(shí)問(wèn)題,且是固定的時(shí)間出現(xiàn)了固定的時(shí)差問(wèn)題。
經(jīng)過(guò)排查,發(fā)現(xiàn)是JVM的默認(rèn)時(shí)區(qū)為
Asia/Shanghai,兩者不一致,然后Asia/Shanghai 這個(gè)時(shí)區(qū)并不一定與GMT+08這個(gè)時(shí)區(qū)相等,他們是2種定義標(biāo)準(zhǔn)。
Asia/Shanghai 這個(gè)代表的是中國(guó)的時(shí)區(qū),但在歷史中,有國(guó)家(包含中國(guó))政策頒布了在1986-1991年等還存在夏令時(shí)。
在這樣的時(shí)間區(qū)間,夏季時(shí),會(huì)將時(shí)間撥快1個(gè)小時(shí)(即東9區(qū)時(shí)間),夏季結(jié)束時(shí)會(huì)再次將時(shí)間撥回一個(gè)小時(shí)(即東8區(qū)時(shí)間)。
所以要保證程序顯示的時(shí)間沒(méi)有問(wèn)題,需要將JVM和spring.jackson.time-zone設(shè)置的時(shí)區(qū)保持一致即可解決問(wèn)題。
JVM中設(shè)置為
Asia/Shanghai,經(jīng)代碼調(diào)試出現(xiàn)的底層時(shí)區(qū)調(diào)整的測(cè)試案例。
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author Ashen
* @date 16/07/2019
*/
public class Test {
public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
static int[] offsets = {
28800000,
29143000,
32400000,
3600000
};
public static void main(String[] args) {
test2();
}
public static void test1(){
Date date0 = new Date(1986 - 1900, 07 - 1, 29);
Date date1 = new Date(1980 - 1900, 07 - 1, 29);
Date date2 = new Date(1988 - 1900, 07 - 1, 29);
}
public static void test2() {
// 以下為JVM中時(shí)區(qū)為:Asia/Shanghai時(shí)的偏移量參數(shù)值(共9對(duì),分別為9年夏令時(shí)的開(kāi)啟與結(jié)束點(diǎn))
long transitions[] = {
-9048018124799999L,
-8918966038528000L,
-3823593062399950L,
-3781140480000000L,
-3722379263999950L,
-3651969024000000L,
2111569920000050L,
2158623129600000L,
2232955699200050L,
2287440691200000L,
2361773260800050L,
2416258252800000L,
2493068083200050L,
2547553075200000L,
2621885644800050L,
2676370636800000L,
2750703206400050L,
2805188198400000L,
8660385792000000L
};
for(int i=0;i<18;i++){
Long longTime = transitions[i] >> 12;
Long field2 = transitions[i] << 52 >> 60;
Long field3 = transitions[i] << 56 >> 60;
Long field4 = transitions[i] << 60 >> 60;
Date date = new Date(longTime);
System.out.println("時(shí)間"+getIndexStr(i)+": "+sdf.format(date)+" 保留值>>"+field2+" 日光節(jié)約量 >> "+getOffset(field3)+" GMT偏移量 >> "+getOffset(field4));
}
}
public static String getIndexStr(int i){
if(i<10) return "0"+i;
else return String.valueOf(i);
}
public static String getOffset(long offset){
return offsets[(int)offset]/(1000 *60* 60)+"小時(shí),";
}
}
下面為運(yùn)行結(jié)果:清晰的看到Asia/Shanghai 時(shí)區(qū)的調(diào)整時(shí)間點(diǎn)與調(diào)整量。
transitions[] 中的值來(lái)源于DEBUG程序時(shí)復(fù)制jvm中的數(shù)據(jù)。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
eclipse啟動(dòng)出現(xiàn)“failed to load the jni shared library”問(wèn)題解決
這篇文章主要介紹了eclipse啟動(dòng)出現(xiàn)“failed to load the jni shared library”問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
Java中String類的常見(jiàn)方法超詳細(xì)講解
這篇文章主要介紹了Java中String類常見(jiàn)方法的相關(guān)資料,String類是不可變的,字符串常量池用于存儲(chǔ)字符串字面量,常用方法包括字符串查找、轉(zhuǎn)換、比較、替換、拆分和截取,需要的朋友可以參考下2025-04-04
Java利用策略模式優(yōu)化過(guò)多if else代碼
這篇文章主要介紹了Java利用策略模式優(yōu)化過(guò)多if else代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
SpringCloud的網(wǎng)關(guān)Zuul和Gateway詳解
SpringCloudZuul和SpringCloudGateway都是用于構(gòu)建微服務(wù)架構(gòu)中的API網(wǎng)關(guān)的組件,但SpringCloudGateway在性能、功能特性和生態(tài)支持等方面有一些優(yōu)勢(shì),因此推薦使用SpringCloudGateway作為首選2025-02-02
使用@RequestParam設(shè)置默認(rèn)可以傳空值
這篇文章主要介紹了使用@RequestParam設(shè)置默認(rèn)可以傳空值的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
SpringBoot CommandLineRunner應(yīng)用啟動(dòng)后執(zhí)行代碼實(shí)例
本文將深入探討CommandLineRunner的工作原理、使用場(chǎng)景及最佳實(shí)踐,幫助開(kāi)發(fā)者充分利用這一功能,構(gòu)建更加健壯的Spring Boot應(yīng)用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04
老生常談Java?網(wǎng)絡(luò)編程?——?Socket?詳解
這篇文章主要介紹了Java?網(wǎng)絡(luò)編程?——?Socket?相關(guān)知識(shí),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05

