一、问题描述

前段时间遇到一个很神奇且费解的问题,程序将用户的生日从日期类型转为string类型时,竟然莫名其妙的少了一天,具体表现为存在数据库的19900916这个日期,取出到程序后做转换为字符串的操作,然后神奇的变为了19900915,并且在开发环境重现时出现了有些同事能够重现,而有些同事无法复现的情况。最终,我们发现了问题的原因,真的可谓是你意想不到的坑之一。

如下图为问题复现:

可见19900906经过日期转换后依然为

Sun Sep 16 00:00:00 CDT 1990

但是获取时间戳,再通过时间戳进行时间转换的时候日期就变成了

1990-09-15T08:23:00.000+08:00

可以看出,时间少了一个小时,如果只看年月日的话就是日期少了一天。

二、夏令时制度

在解答这个问题的时候,不得不先介绍夏令时的概念

夏时制,又称“日光节约时制”(Daylight Saving Time),是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时”。一般在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。各个采纳夏时制的国家具体规定不同。目前全世界有近110个国家每年要实行夏令时.

而且中国也有一段时间实行过夏令时制度,惊喜吧。

我国解放前几年在部分地区也曾实行过夏令时。1986年4月,中央有关部门发出“在全国范围内实行夏时制的通知”,具体作法是:每年从四月中旬第一个星期日的凌晨2时整(北京时间),将时钟拨快一小时,即将表针由2时拨至3时,夏令时开始;到九月中旬第一个星期日的凌晨2时整(北京夏令时),再将时钟拨回一小时,即将表针由2时拨至1时,夏令时结束。从1986年到1991年的六个年度,除1986年因是实行夏时制的第一年,从5月4日开始到9月14日结束外,其它年份均按规定的时段施行。1992年起,夏令时暂停实行。

1935年至1951年,每年5月1日至9月30日

1952年3月1日至10月31日

1953年至1954年,每年4月1日至10月31日

1955年至1956年,每年5月1日至9月30日

1957年至1959年,每年4月1日至9月30日

1960年至1961年,每年6月1日至9月30日

1974年至1975年,每年4月1日至10月31日

1979年7月1日至9月30日

1986年至1991年,每年4月中旬的第一个星期日2时起至9月中旬的第一个星期日2时止。具体如下:

1986年5月4日至9月14日,

1987年4月12日至9月13日,

1988年4月10日至9月11日,

1989年4月16日至9月17日,

1990年4月15日至9月16日,

1991年4月14日至9月15日。

在实行夏时制期间出生者,其实际出生时间应为当时的出生时间须减去1小时,即:将调快的1小时减回来。因此,如为实行夏时制时期出生,如当时记录的出生时间是夏令时,请注意将夏令时前推一小时方为实际出生时间。

例如夏令时公历1991年5月2日0点10分出生,则将夏令时换算为正常时间即 1991年5月1日23点10出生。

看来,如果用户生日假如真的是1990-09-16 00:00:00,并且这个时间为夏令时的话,那么他的生日确实是1990-09-15 23:00:00。可是用户才不会听你解释什么夏令时,你给他把生日计算错了,他就会投诉你。接下来在让我们看看java程序为什么会算错呢?

原来java的Date类型遵循Unix时间规则,将1970-01-01 00:00:00为世界纪元起点,以毫秒为单位。内部存放的Time为long型,返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。当我们使用中国夏令时获取到的long型时间,然后使用toString()做转换的时候java自动减少了一小时,也就获得了之后不正确的时间。

三、jdk版本区别

加入真的有这个坑的话,为什么我们最近才发现,之前一直没有遇到过呢,并且我们为什么有些人能够复现,有些人却复现不了呢?带着这个问题,我们继续追查,最终发现原来是jdk版本的差别。

大家注意上面那个有问题的是基于jdk1.8.0_201,而下列这张图是基于jdk1.8.0_131的,就没有出现该类问题,可以推测比jdk1.8.0_201的版本可能都有此类问题。所以难道是jdk版本升级内置了对于中国夏令时那段时间的支持?如果真是如此的话,不得不佩服jdk开发人员的细致程度,但也给我带来了一次不大不小的坑。

四、解决方法

1.使用SimpleDateFormat.format的方法没发现有此类问题

2.使用Calendar类,虽然繁琐一点

3.最推荐的方法:

设置应用的

TimeZone.setDefault(TimeZone.getDefault().getTimeZone("GMT+8"));

或加启动参数

-Duser.timezone=GMT+8

附一张使用GMT(格林尼治标准时间-也叫世界时)的结果图

谢谢阅读,希望你能避免此坑~

---------------------------------------------------------------------------------我是分割线--------------------------------------------------------------------------

to be a better me, talk is cheap show me the code

版权所有,转载请注明原文链接。

文中有不妥或者错误的地方还望指出,以免误人子弟。如果觉得本文对你有所帮助不妨【点赞】一下!如果你有更好的建议,可以给我留言讨论,共同进步!

再次感谢您耐心的读完本篇文章。

java 夏令时 重置偏移量_那些年我们踩过的坑——Java中Date夏令时日期转换不一致问题...相关推荐

  1. 那些年我们踩过的坑,SQL 中的空值陷阱!

    那些年我们踩过的坑,SQL 中的空值陷阱! 置顶 不剪发的Tony老师 2019-12-31 07:31:17 6737 收藏 66 分类专栏: SQL 文章标签: sql 空值 mysql orac ...

  2. 西工大java高级网络编程_西工大16春《JAVA高级网络编程》平时作业

    西工大16春<JAVA高级网络编程>平时作业 7 o& [9 w  ^# D  Z一.单选题:[25道,总分:100分]5 z# ?* Z! M% M1 h4 R# n. D+ a ...

  3. 中秋节图案 用java代码打出来_这个中秋,我用 Java 画了一个月饼!

    栈长代表微信公众号 "Java技术栈" 祝所有粉丝中秋佳节快乐! 为了用一种特殊的方式表达我的心意,去年中秋节,我写了这篇文章: 没错,去年一天,我学了 20 种编程语言,刺激.. ...

  4. java生成pdf图表_开发员指南:使用Java图表转换为PDF/JPG等图像

    Aspose.Cells for JavaExcel电子表格处理API,它允许Java开发人员在自己的Java应用程序中嵌入可读取.写入和操作Excel电子表格的能力,而无需依赖Microsoft E ...

  5. java spring框架 注解_史上最全的java spring注解

    史上最全的java spring注解,没有之一 注解是个好东西,但好东西我们也是看见过,整理过,理解过,用过才知道好.不求我们每个都记住,但求保有印象,在需要的时候能提取出来再查找相关资料,平时工作就 ...

  6. java泛型 简书_一文带你认识Java泛型基础

    Java泛型基础 1. 认识泛型 泛型是在JDK1.5之后增加的新功能. 泛型可以解决数据的安全性问题, 主要的原理是在类声明的时候通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型. ...

  7. java语言程序设计你_清华大学出版社-图书详情-《Java语言程序设计》

    前言 Java语言是一种典型的面向对象的.跨平台的.支持分布式和多线程的优秀编程语言,具有极强的扩展性.自其诞生以来,迅速被业界认可并广泛应用于Web应用程序的开发中.在此形势下,国内高校在计算机及相 ...

  8. mac上java文件如何编译_如何在Mac上用Java编译和运行程序?

    小编典典 在Mac OSX或任何主要操作系统上编译和运行Java应用程序非常容易.Apple随OSX一起提供了一个功能齐全的Java运行时和开发环境,因此您要做的就是编写Java程序并使用内置工具来编 ...

  9. java编程最新图书_清华大学出版社-图书详情-《Java程序设计》

    前言 Java是一种完全面向对象的程序设计语言,具有卓越的通用性.高效性.平台移植性和安全性,得到广泛的应用.在全球云计算和移动互联网产业高速发展的环境下,Java具备显著的优势和广阔前景.本书以Ja ...

最新文章

  1. Java 树形结构数据生成--不需要顶级节点
  2. 病毒式营销案例:多芬让“病毒”的诱惑自发传递
  3. 【9702】黑白棋的移动
  4. HTK下yes/no的识别
  5. Java反射机制深度剖析
  6. 微盟数据已经全面找回 并公布商家赔付计划
  7. hping 详解_hping3使用
  8. Django中文文档
  9. 泛函、变分与欧拉-拉格朗日方程
  10. 4G物联网卡使用记录——使用方法及被锁卡处理
  11. 怎么彻底卸载cad2017_Win10系统怎么彻底卸载cad【图文教程】
  12. STM32核心板设计——电源设计
  13. 茶叶蛋大冒险全部攻略
  14. 《5K入门级项目实战:好来屋在线影院》之第 9 战 —— 电影信息管理
  15. 安徽赛区-云巡未来-第十一届全国大学生电子商务“创新、创意及创业”挑战赛 赛后总结
  16. c语言什么事结构体,C语言结构体定义是什么
  17. 计算机等级考试——三级网络技术
  18. 认知无线电网络架构与协议体系
  19. pid:1 nid:null exception:channel:can't restart by no select live node
  20. 【软件工程-Teamwork 2】必应词典软件手机版测试报告

热门文章

  1. 您尚未完成合并(MERGE_HEAD存在)
  2. 【Gas优化】超优化 By Max-SMT
  3. 苹果2021年第一季度推出新款 iPad Pro
  4. linux 关闭所有文件描述符,close - 关闭一个文件描述符
  5. Bonding工作模式介绍
  6. linux如何使history命令可以显示更多信息
  7. 还记得“童年回忆”小霸王吗?现在它要打造市值500亿的VR产业
  8. dpdk 程序绑核失败问题:EAL: pthread_setaffinity_np failed
  9. Java学习笔记之二:Maven中依赖使用exclusions设置,来解决依赖冲突
  10. 助力新型工业化,曙光启动智慧工业战略