【经验】java时区问题

首先得有一个预备知识
时间戳:指1970-01-01 00:00:00(GMT/UTC)起到当前的毫秒数。与时区无关,不同时区同一个时刻的时间戳是相同的。所以,时间戳不受时区影响。但是,不同时区的国家同一个时间戳显示的日期不同,所以同一时刻的时间戳表示的日期会受时区影响。

一、MySQL数据库连接时区问题

  1.jdbc连接时设置serverTimezone。
  由于后台生成properties文件jdbc连接并没有区分国内外服务器时区,统一用的中国时区Asia/Shanghai,所以库timestamp类型字段都显示成了国内的时间。
  解决办法:如果项目并没有上线,则可以使用JDK的默认时区,设置serverTimezone为JDK的默认时区

ZoneId.systemDefault();

也是系统的时区,这样保证了数据库timestamp字段日期跟系统保持一致;如果项目上线后,则不能修改,保持不变。修改后后会影响原来的涉及日期的逻辑。 如果有操作系统时区会更变的情况下,需要程序监听时区的变化。重设默认时区。

  2.jdbc连接时不设置serverTimezone。
  会有JDK,MySQL关于CST标准冲突导致的时区问题。
  当未设置serverTimezone时,数据库将连接使用MySQL服务端的time_zone(全局时区),默认值为CST。time_zone的默认值为SYSTEM,而SYSTEM取的是system_time_zone(系统时区)的值,system_time_zone的默认值就是CST。
  MySQL中,CST表示的是:中国标准时间(UTC+08:00)。
  JDK中,CST表示的是:美国标准时间(UTC-05:00或UTC-06:00)。
  由于JDK和MySQL服务端对CST时区的不同标准(可能是下载的地址版本不同),会导致时间问题。
  解决办法:jdbc连接时设置serverTimezone。

二、夏冬令时变化导致的时区问题

  在程序中,如果涉及天数的计算,需要根据实际情况选择不同的计算规则。如果要用日期,则全部用日期为标准计算;如果要用时间戳,则全部用时间戳为标准计算。检查使用的每一个时间工具,计算是用的日期还是时间戳。否则会由于夏冬令时的变化导致时区问题。
  比如,在hutool工具中,DateUtil工具中offsetDay方法,计算偏移30天后的日期,是根据时区为标准获得的日期。如果初始日期是冬令时某天的零点,偏移天数后的日期是夏令时某天的零点,但是由于转变为夏冬令时会让日期直接快/慢一个小时,导致前后的时间在当前时区的时间戳,跟以时间戳为标准计算天数的betweenDay方法,计算出来的天数不同。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的时区概念是非常重要的,因为在开发中需要处理不同时区间。下面是关于Java时区的一些详解: 1. 世界时区 全球被分为24个时区,每个时区都有一个对应的UTC偏移量,表示该地区与协调世界(UTC)之间的差异。例如,北京间是UTC+8,纽约间是UTC-5。 2. Java时区 Java中的时区使用了ID来标识。它们遵循了IETF的时区标识符,例如“America/New_York”和“Asia/Shanghai”。这些ID是唯一的,并且对应于特定的时区偏移量和时区规则。 3. 时区的转换 使用Java中的DateTimeFormatter类,可以将间从一个时区转换为另一个时区。例如,将纽约间转换为北京间: ``` DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime dateTime = LocalDateTime.parse("2022-06-30 10:30:00", formatter); ZoneId newYorkZone = ZoneId.of("America/New_York"); ZoneId beijingZone = ZoneId.of("Asia/Shanghai"); ZonedDateTime newYorkTime = ZonedDateTime.of(dateTime, newYorkZone); ZonedDateTime beijingTime = newYorkTime.withZoneSameInstant(beijingZone); System.out.println(beijingTime.format(formatter)); ``` 4. 时区的默认值 Java中的时区默认值是系统时区。可以使用System类的getProperty()方法获取系统时区: ``` System.out.println(System.getProperty("user.timezone")); ``` 5. 时区的设置 可以使用System类的setProperty()方法设置时区: ``` System.setProperty("user.timezone", "Asia/Shanghai"); ``` 需要注意的是,时区设置必须在程序启动进行,否则可能会出现意料之外的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值