[JAVA] JVM默认时区为:Asia/Shanghai与java程序中GMT+08不一致异常

1948 0
王子 2022-11-8 17:39:32 | 显示全部楼层 |阅读模式
目录

    经过排查,发现是JVM的默认时区为JVM中设置为

在Spring程序中配置了spring.jackson.time-zone=GMT+08时,部分时间相差一个小时问题,且是固定的时间出现了固定的时差问题。

经过排查,发现是JVM的默认时区为

Asia/Shanghai,两者不一致,然后Asia/Shanghai 这个时区并不一定与GMT+08这个时区相等,他们是2种定义标准。
Asia/Shanghai 这个代表的是中国的时区,但在历史中,有国家(包含中国)政策颁布了在1986-1991年等还存在夏令时。
在这样的时间区间,夏季时,会将时间拨快1个小时(即东9区时间),夏季结束时会再次将时间拨回一个小时(即东8区时间)。
所以要保证程序显示的时间没有问题,需要将JVM和spring.jackson.time-zone设置的时区保持一致即可解决问题

JVM中设置为

Asia/Shanghai,经代码调试出现的底层时区调整的测试案例。
  1. import java.text.SimpleDateFormat;
  2. import java.util.Date;
  3. /**
  4. * @author Ashen
  5. * @date 16/07/2019
  6. */
  7. public class Test {
  8.         public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
  9.         static int[] offsets = {
  10.                         28800000,
  11.                         29143000,
  12.                         32400000,
  13.                         3600000
  14.         };
  15.         public static void main(String[] args) {
  16.                 test2();
  17.         }
  18.         public static void test1(){
  19.                 Date date0 = new Date(1986 - 1900, 07 - 1, 29);
  20.                 Date date1 = new Date(1980 - 1900, 07 - 1, 29);
  21.                 Date date2 = new Date(1988 - 1900, 07 - 1, 29);
  22.         }
  23.         public static void test2() {
  24.                 // 以下为JVM中时区为:Asia/Shanghai时的偏移量参数值(共9对,分别为9年夏令时的开启与结束点)
  25.                 long transitions[] = {
  26.                                 -9048018124799999L,
  27.                                 -8918966038528000L,
  28.                                 -3823593062399950L,
  29.                                 -3781140480000000L,
  30.                                 -3722379263999950L,
  31.                                 -3651969024000000L,
  32.                                 2111569920000050L,
  33.                                 2158623129600000L,
  34.                                 2232955699200050L,
  35.                                 2287440691200000L,
  36.                                 2361773260800050L,
  37.                                 2416258252800000L,
  38.                                 2493068083200050L,
  39.                                 2547553075200000L,
  40.                                 2621885644800050L,
  41.                                 2676370636800000L,
  42.                                 2750703206400050L,
  43.                                 2805188198400000L,
  44.                                 8660385792000000L
  45.                 };
  46.                 for(int i=0;i<18;i++){
  47.                         Long longTime = transitions[i] >> 12;
  48.                         Long field2 = transitions[i] << 52 >> 60;
  49.                         Long field3 = transitions[i] << 56 >> 60;
  50.                         Long field4 = transitions[i] << 60 >> 60;
  51.                         Date date = new Date(longTime);
  52.                         System.out.println("时间"+getIndexStr(i)+": "+sdf.format(date)+" 保留值>>"+field2+" 日光节约量 >> "+getOffset(field3)+" GMT偏移量 >> "+getOffset(field4));
  53.                 }
  54.         }
  55.         public static String getIndexStr(int i){
  56.                 if(i<10) return "0"+i;
  57.                 else return String.valueOf(i);
  58.         }
  59.         public static String getOffset(long offset){
  60.                 return offsets[(int)offset]/(1000 *60* 60)+"小时,";
  61.         }
  62. }
复制代码
下面为运行结果:清晰的看到Asia/Shanghai 时区的调整时间点与调整量。
transitions[] 中的值来源于DEBUG程序时复制jvm中的数据。


以上为个人经验,希望能给大家一个参考,也希望大家多多支持中国红客联盟。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行