JDK不同版本时区问题

1、问题描述

项目中通过时区名称转换为本地时间(JDK11.0.1),与数据库(Postgresql12.3)转换出来的本地时间相差一小时。当时相差一小时就怀疑是夏令时的问题造成的,但百度也没有找到处理办法,后面直接去jdk官网去看终于给找到原因。这是由于jdk时区库没有更新(lib/tzdb.dat),因为时区每年都会更新很多次,如果下载到本地的jdk的这个库没有更新,就有可能造成某些时区的时间转换有问题。

2、测试代码

Postgresql根据时区获取本地时间:

SELECT NOW() AT TIME ZONE 'America/Santiago';

Java根据时区名称转换本地时间(在JDK的时区库没有更新的情况下JDK11.0.1与JDK11.0.11执行的结果都还不一样,其它版本的也会存在该问题):

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class TimeZoneTest{
    public static void main(String[] args){
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String zoneName = "America/Santiago";
        ZoneId zoneId;
        try{
            zoneId = ZoneId.of(zoneName);
        }catch(Exception e){
            zoneId = ZoneId.of(ZoneId.SHORT_IDS.get(zoneName));
        }
        ZoneOffset offset = zoneId.getRules().getOffset(Instant.now());
        String time = OffsetDateTime.now().toInstant().atOffset(offset).format(fmt);
        System.out.println(String.format("\n\ntzName : %s, offset : %s, time : %s\n\n",offset,offset.getTotalSeconds(),time));
    }
}

3、查看JDK本地时区库版本

下载官方的tzupdater工具,完成后执行以下命令查看(tzupdater说明文档):

java -jar tzupdater.jar -V

4、更新JDK本地时区库

java -jar tzupdater.jar -l

完成后再执行第2点中的测试代码,这时转换的本地时间就正常了。

5、其它相关资源

JDK不同版本对应的时区库版本地址:https://www.oracle.com/java/technologies/tzdata-versions.html

JDK时区相关的文档地址:https://www.oracle.com/java/technologies/javase/timezones.html

时区库地址:https://www.iana.org/time-zones

你可能感兴趣的:(JDK不同版本时区问题)