现象

项目中计算证书开始和结束两个时间点之间的时间差(天数),同样的代码在国内正常运行,计算的天数和预期一致;但是在欧洲运行时计算的天数比国内的天数少了一天,导致校验失败。

代码逻辑如下:

private static void calcDaysWithDate(String startTime, String endTime) throws ParseException {SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");Date start = format.parse(startTime);Date end = format.parse(endTime);long oneDayTime = 86_400_000L;long between = (end.getTime() - start.getTime()) / oneDayTime;System.out.println("Date Api: " + startTime + " to " + endTime + " : " + between + " days.");
}

将证书的开始和结束时间字符串转为Date类型,然后获取相应的时间戳,最后时间戳相减除以一天毫秒数,得到两个时间点之前相差的天数。
该代码之前在国内和欧洲运行都没问题,直到最近的一次修改,修改原因是证书即将到期,导致结束时间不能向后延,在新证书申请下来之前,暂时将时间间隔缩短了三个月,之前都是整年的间隔。刚开始考虑是否是时差导致的,但是转念一想这里计算的是时间差,不是时间点;如果有时差,开始时间和结束时间都有时差,结果也应该是正常的。
分析了好久也没往夏令时和冬令时上想,但是问题还是得解决,看着上面的代码使用的是老的Date类,本着死马当活马医的想法,就用1.8的LocalDate试试,结果还真有效果。
代码如下:

private static void calcDaysWithLocalDate(String startTime, String endTime){DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d");LocalDate start = LocalDate.parse(startTime, formatter);LocalDate end = LocalDate.parse(endTime, formatter);long between = ChronoUnit.DAYS.between(start, end);System.out.println("LocalDate Api: " + startTime + " to " + endTime + " : " + between + " days.");
}

受此启发,然后就将代码中计算的时间粒度变小一些,计算两个时间点相差的小时数,原因就在这里找到了,同样的代码在欧洲比国内少了一个小时,因为代码中按天计算并使用long来接收结果,导致结果取整就少了一天。
到这里就明了了,就是代码逻辑不严谨以及夏令时和冬令时的问题导致的,但是为什么之前没有遇到这个问题呢?
分析发现,因为之前证书的有效期都是整年,开始时间在冬令时,结束时间也在冬令时,就正好不会出现这个问题。而本次修改将有效期减少了三个月,导致存在开始时间可能在冬令时,而结束时间在夏令时的情况,这就导致了两个时间点之间的时间差少了一个小时。实际情况也是在11月才开始在生产出现该问题。
至此,问题也得到了解决,修改代码,使用1.8新的api – LocalDate实现。
完整代码如下:

public class DateDemo {public static void main(String[] args) throws ParseException {String startDate = "2021-11-10";String endDate = "2041-08-07";calcDaysWithDate(startDate, endDate);calcDaysWithLocalDate(startDate, endDate);String startDateTime = "2021-11-10 00:00:00";String endDateTime = "2041-08-07 00:00:00";calcDaysWithLocalDateTime(startDateTime, endDateTime);calcDaysWithDateTime(startDateTime, endDateTime);}private static void calcDaysWithDate(String startTime, String endTime) throws ParseException {SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");Date start = format.parse(startTime);Date end = format.parse(endTime);long oneDayTime = 86_400_000L;long between = (end.getTime() - start.getTime()) / oneDayTime;System.out.println("Date Api: " + startTime + " to " + endTime + " : " + between + " days.");}private static void calcDaysWithDateTime(String startTime, String endTime) throws ParseException {SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date start = format.parse(startTime);Date end = format.parse(endTime);long oneDayTime = 3_600_000L;long between = (end.getTime() - start.getTime()) / oneDayTime;System.out.println("DateTime Api: " + startTime + " to " + endTime + " : " + between + " hours.");}private static void calcDaysWithLocalDate(String startTime, String endTime) {DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d");LocalDate start = LocalDate.parse(startTime, formatter);LocalDate end = LocalDate.parse(endTime, formatter);long between = ChronoUnit.DAYS.between(start, end);System.out.println("LocalDate Api: " + startTime + " to " + endTime + " : " + between + " days.");}private static void calcDaysWithLocalDateTime(String startTime, String endTime) {DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");LocalDateTime start = LocalDateTime.parse(startTime, formatter);LocalDateTime end = LocalDateTime.parse(endTime, formatter);long between = ChronoUnit.HOURS.between(start, end);System.out.println("LocalDateTime Api: " + startTime + " to " + endTime + " : " + between + " hours.");}
}

记录一次夏令时和冬令时导致的项目BUG相关推荐

  1. 时区、时间戳、日期、夏令时、冬令时

    关键词:时区.时间戳.日期.夏令时.冬令时 一.日期时间 就是一个日期,比如现在是北京时间2023年3月5日14:25:20,在说起日期时间的时候,一定要说清楚是哪里的时间,因为不同国家之间因为地理位 ...

  2. 【Java编程系列】Java判断世界各时区的夏令时、冬令时

    热门系列: [Java编程系列]java用POI.Itext生成并下载PPT.PDF文件 [Java编程系列]二进制如何表示小数?0.3+0.6为什么不等于0.9?纳尼!!! 程序人生,精彩抢先看 目 ...

  3. Java时区处理之夏令时,冬令时 - 美国的6个时区

    在开始之前,如果要了解Java中的时区操作的基本概念和事例,可以参见另一篇博客:Java时区处理之Date,Calendar,TimeZone,SimpleDateFormat 一.夏令时概述: Da ...

  4. 安卓国际化开发中的时区问题之——夏令时,冬令时

    在说时区问题的时候,估计很多人都很不屑.因为获取时区的方法真的太简单了.尤其是很多面向百度编程的iter. 比如,获取时区的方法一句就能搞定: String timeZone ="GMT&q ...

  5. 【记录】IDEA未正确关闭导致打开报错,进不了主界面,含解决办法

    [记录]IDEA未正确关闭导致打开报错,进不了主界面,含解决办法 错误提示 解决方案 参考 错误提示 截取了错误的主要部分 java.util.concurrent.CompletionExcepti ...

  6. 冬令时 java_java处理 夏令时、冬令时问题

    最近接到一个需求: 给一个在美国洛杉矶时区(America/Los_Angeles)的机器上生成的long的时间,要在中国时区的机器上,把这个时间转换成美国时间? 业务方提醒,需要特别主要夏令时.冬令 ...

  7. java timezone解决夏令时、冬令时问题

    1. 方式一:通过IP查询API,获取当地时间 API说明 https://ipinfo.io/{ip}?token={token} {     "ip": "91.80 ...

  8. MemoryCache 使用不当导致的一个 BUG

    MemoryCache 使用不当导致的一个 BUG Intro 前几天发现代码里的一个 BUG,原因是 MemoryCache 使用不当,可以对于很多人来说可能都知道,但还是想分享记录一下,避免以后写 ...

  9. java redis使用卡死_记一次找因 redis 使用不当导致应用卡死 bug 的过程

    原标题:记一次找因 redis 使用不当导致应用卡死 bug 的过程 作者:小木 my.oschina.net/xiaomu0082/blog/2990388 首先说下问题现象:内网sandbox环境 ...

  10. 【BUG记录】记一次游戏越来越卡的BUG

    [BUG记录]记一次游戏越来越卡的BUG U3D的MOBA项目,测试过程中,10分钟以后,游戏帧率开始缓慢下降,约3-5分钟后,由60帧下降到小于10帧,编辑器模式. 打开profiler,看到CPU ...

最新文章

  1. 2020人工智能课程超级大列表:深度学习-强化学习-图神经网络-自然语言处理等...
  2. 数据数字mongodb 模糊查询以及$type使用
  3. 【Android 内存优化】Bitmap 长图加载 ( BitmapRegionDecoder 简介 | BitmapRegionDecoder 使用流程 | 区域解码加载示例 )
  4. Innodb存储引擎的缓存命中率计算
  5. memcache在ThinkPHP中的使用1---PHP下安装memcache
  6. 高等数学上-赵立军-北京大学出版社-题解-练习6.1
  7. python apscheduler执行_python apscheduler 每两小时执行一次
  8. std::make_shared<T>/std::make_unique<T>与std::shared_ptr<T>/std::unique_ptr<T>的区别与联系
  9. 基于Java+SpringBoot+vue+element实现前后端分离牙科诊所管理系统详细设计
  10. 【Excel】统计不重复数据的个数,设置单元格不允许出现重复数据
  11. 魔力转圈圈(快速幂)
  12. Remoting例子-使用配置文件
  13. linux df 查看磁盘剩余空间,du查看文件占用多少空间,rm -rf 删除文件 mkdir -p创建目录(含父级)
  14. 2020互联网公司中秋礼盒大比拼!
  15. 职称论文发表教育期刊《中小学教育》杂志简介及投稿须知
  16. 移动应用的必杀技:超级app+轻应用
  17. 002 splitter
  18. Bmob后端云学习(未完)
  19. 【洛谷】P2298 Mzc和男家丁的游戏*
  20. 饼图加引导线_如何在饼形图中添加引导线(Excel)/

热门文章

  1. C# wpf 自定义标题栏及无边框窗口
  2. 路科sv练习2-类的继承
  3. 2016北大叉院、北大信科保研经历
  4. 手机游戏修改客户端服务器,服务器 客户端手机游戏
  5. FFmpeg —— ffplay源码 - 制作桌面动态壁纸
  6. unantu下的tmp文件夹_Ubuntu根目录下各文件夹的功能详细介绍
  7. 研究生英语期末复习(Unit3)
  8. 基于android studio真机连接本地服务器(Apache)详细流程
  9. JavaScript入门语法
  10. TP5 查询条件总结