一,先看看中国的夏令时

1986年至1991年,中华人民共和国在全国范围实行了六年夏令时,每年从4月中旬的第一个星期日2时整(北京时间)到9月中旬第一个星期日的凌晨2时整;
  十日为旬。 上旬 每月第一日至第十日的十天,为上旬。 中旬 每月十一日到二十日的十天,为中旬,下旬同理

可以通过如下代码找出这6的异常点

     public static void testDayTime(TimeZone timeZone){SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println("Time Zone is " + timeZone.getDisplayName() + " " + timeZone.getID());Calendar start = Calendar.getInstance(timeZone);start.setTime(new Date(0));//UTC 1970-01-01System.out.println("start=" + fmt.format(start.getTime()));long end = Calendar.getInstance(timeZone).getTimeInMillis();//current timeboolean find = false;for(long i = start.getTimeInMillis(); i < end; i= start.getTimeInMillis() ){start.add(Calendar.DATE, 1); //add one dayif((start.getTimeInMillis() - i)%(24*3600*1000L) != 0){find = true;System.out.println("from " + fmt.format(new Date(i)) +"to " + fmt.format(start.getTime()) +" has " + (start.getTimeInMillis() - i) + "ms" +"[" + (start.getTimeInMillis() - i)/(3600*1000L) + "hours]");}}if(!find){System.out.println("Every day is ok.");}}public static void main(String argv[] ) throws Exception{TimeZone timeZone = TimeZone.getDefault();WhatTime.testDayTime(timeZone);System.out.println("----------------------------------------------------------------");timeZone = TimeZone.getTimeZone("GMT");WhatTime.testDayTime(timeZone);}
from 1986-05-03 08:00:00to 1986-05-04 08:00:00 has 82800000ms[23hours]
from 1986-09-13 08:00:00to 1986-09-14 08:00:00 has 90000000ms[25hours]
from 1987-04-11 08:00:00to 1987-04-12 08:00:00 has 82800000ms[23hours]
from 1987-09-12 08:00:00to 1987-09-13 08:00:00 has 90000000ms[25hours]
from 1988-04-09 08:00:00to 1988-04-10 08:00:00 has 82800000ms[23hours]
from 1988-09-10 08:00:00to 1988-09-11 08:00:00 has 90000000ms[25hours]
from 1989-04-15 08:00:00to 1989-04-16 08:00:00 has 82800000ms[23hours]
from 1989-09-16 08:00:00to 1989-09-17 08:00:00 has 90000000ms[25hours]
from 1990-04-14 08:00:00to 1990-04-15 08:00:00 has 82800000ms[23hours]
from 1990-09-15 08:00:00to 1990-09-16 08:00:00 has 90000000ms[25hours]
from 1991-04-13 08:00:00to 1991-04-14 08:00:00 has 82800000ms[23hours]
from 1991-09-14 08:00:00to 1991-09-15 08:00:00 has 90000000ms[25hours]
----------------------------------------------------------------

然后我们再准确的找下是那几个时间点有问题

//
//     比如1986年的夏令时时间,从代码来看,是从1986-05-04 00:00:00到1986-09-13 22:59:59
//     但是java也不一定对,需要看老人或者看当年的报纸才能知道准确的夏令时时间@Testpublic void test4() throws Exception {SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");TimeZone zone = TimeZone.getDefault();Date d12=sf.parse("1986-05-03 23:59:00");//Date d13=sf.parse("1986-05-04 00:00:00");//Date d14=sf.parse("1986-06-04 00:00:00");//Date d15=sf.parse("1986-09-13 22:59:59");// Date d16=sf.parse("1986-09-13 23:00:00");// //突变点System.out.println("===1986-05-04 00:00:00实际时间====="+sf.parse("1986-05-04 00:00:00").toLocaleString());System.out.println("===1986-09-13 22:59:59实际时间====="+sf.parse("1986-09-13 22:59:59").toLocaleString());System.out.println("===1986-09-13 23:00:00实际时间====="+sf.parse("1986-09-13 23:00:00").toLocaleString());System.out.println("===1986-09-13 23:59:59实际时间====="+sf.parse("1986-09-13 23:59:59").toLocaleString());Date d21=sf.parse("1987-04-11 23:59:00");//Date d22=sf.parse("1987-04-12 00:00:00");//Date d23=sf.parse("1987-09-12 22:59:59");//Date d24=sf.parse("1987-09-12 23:00:00");//Date d31=sf.parse("1988-04-09 23:59:59");//Date d32=sf.parse("1988-04-10 00:00:00");//Date d33=sf.parse("1988-09-10 22:59:59");//Date d34=sf.parse("1988-09-10 23:00:00");//System.out.println("===============");Date d41=sf.parse("1989-04-15 23:59:59");//Date d42=sf.parse("1989-04-16 00:00:00");//Date d43=sf.parse("1989-09-16 22:59:59");//Date d44=sf.parse("1989-09-16 23:00:00");//System.out.println("===============");Date d51=sf.parse("1990-04-14 23:59:59");//Date d52=sf.parse("1990-04-15 00:00:00");//Date d53=sf.parse("1990-09-15 22:59:59");//Date d54=sf.parse("1990-09-15 23:00:00");//System.out.println("===============");Date d61=sf.parse("1991-04-13 23:59:59");//Date d62=sf.parse("1991-04-14 00:00:00");//Date d63=sf.parse("1991-09-14 22:59:59");//Date d64=sf.parse("1991-09-14 23:00:00");//System.out.println("=========1986=======");System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d12));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d13));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d14));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d15));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d16));System.out.println("=========1987=======");System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d21));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d22));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d23));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d24));System.out.println("=========1988=======");System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d31));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d32));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d33));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d34));System.out.println("=========1989=======");System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d41));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d42));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d43));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d44));System.out.println("=========1990=======");System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d51));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d52));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d53));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d54));System.out.println("======1991==========");System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d61));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d62));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d63));System.out.println("目标时区是否使用了夏令时:"+isDaylight(zone, d64));//6个突变点如下,只在开始实行的时候变化System.out.println("===1986-05-04 00:00:00实际时间====="+sf.parse("1986-05-04 00:00:00").toLocaleString());System.out.println("===1987-04-12 00:00:00实际时间====="+sf.parse("1987-04-12 00:00:00").toLocaleString());System.out.println("===1988-04-10 00:00:00实际时间====="+sf.parse("1988-04-10 00:00:00").toLocaleString());System.out.println("===1990-04-15 00:00:00实际时间====="+sf.parse("1990-04-15 00:00:00").toLocaleString());System.out.println("===1991-04-14 00:00:00实际时间====="+sf.parse("1991-04-14 00:00:00").toLocaleString());}//判断是否在夏令时private boolean isDaylight(TimeZone zone,Date date) {//正常逻辑是:时区使用了夏令时再判断时间,这里因为中国取消了if (zone.getID().equals("Asia/Shanghai")) {return  zone.inDaylightTime(date);}return zone.useDaylightTime()&&zone.inDaylightTime(date);}

通过上面,找到了6个突变点:

1986-05-04 00:00:00
1987-04-12 00:00:00

1988-04-10 00:00:00

1989-04-16 00:00:00

1990-04-15 00:00:00

1991-04-14 00:00:00

/**
      * 说明:这6个夏令时日期会导致实际存入数据库的date日期发生变化,比如写的是1986-05-04,实际存入的是1986-05-04 01:00:00
      * 如果之后在数据库里面进行日期匹配的时候会出现问题,你需要trunc(date)来比较
      * 
      * 
      * 这里有2个问题,
      * 1.为什么夏令时结束的时候不会突变呢,比如:1986-09-13 23:00:00这个时候结束了夏令时
      * 按理实际的时间应该是变为:1986-09-13 22:00:00, 结果没有变,那么减少的那一个小时去哪里了呢?怎么体现?(待琢磨。。。)
      * 2.上面得到的夏令时时间范围跟实际规定的真的一样吗?
      * 
      * 下面我们看看美国的夏令时是不是也是这种情况
      */

  //美国的夏令时从三月的第二个周日开始到十一月的第一个周日结束//已知官方2016年:America/New_York的夏令时时间是:  2016-3-13 02:00:00  到  2016-11-06 01:59:59 @Testpublic void test5() throws Exception {// 转换为0时区时间作为参照点SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// sf.setTimeZone(TimeZone.getTimeZone("GMT+0"));TimeZone york = TimeZone.getTimeZone("America/New_York"); // GMT-5sf.setTimeZone(york);Date d1 = sf.parse("2016-03-13 01:59:59");// falseDate d2 = sf.parse("2016-03-13 02:00:00");// trueDate d3 = sf.parse("2016-11-06 00:59:59");// trueDate d3_1 = sf.parse("2016-11-06 01:00:00");// falseDate d3_2 = sf.parse("2016-11-06 01:59:59");// false预计是夏令时时间,实际不是Date d4 = sf.parse("2016-11-06 02:00:00");// false//可以发现,对于夏令时开始的时间判断确实没问题,但是对于夏令时的结束时间判断错误,准确说,提前了一个小时判断了System.out.println("目标时区是否使用了夏令时:" + isDaylight(york, d1));System.out.println("目标时区是否使用了夏令时:" + isDaylight(york, d2));System.out.println("目标时区是否使用了夏令时:" + isDaylight(york, d3));System.out.println("目标时区是否使用了夏令时:" + isDaylight(york, d3_1));System.out.println("目标时区是否使用了夏令时:" + isDaylight(york, d3_2));System.out.println("目标时区是否使用了夏令时:" + isDaylight(york, d4));}
      //再来看下美国夏令时的突变时间@Testpublic void test6() throws Exception {//中间相隔13个小时     中国+8  纽约-5ChangeZone("2016-3-13 14:59:59", "PRC","America/New_York",  "yyyy-MM-dd HH:mm:ss");//2016-03-13 01:59:59ChangeZone("2016-3-13 15:00:00", "PRC","America/New_York",  "yyyy-MM-dd HH:mm:ss");//2016-03-13 03:00:00ChangeZone("2016-11-6 13:59:59", "PRC","America/New_York",  "yyyy-MM-dd HH:mm:ss");//2016-11-06 01:59:59//这个结果是不对的,应该02:00:00,结果还是01:00:00ChangeZone("2016-11-6 14:00:00", "PRC","America/New_York",  "yyyy-MM-dd HH:mm:ss");//2016-11-06 01:00:00}/***通过以上测试可以发现:无论是中国还是美国的夏令时*依然存在上面的2个问题:*1.夏令时在结束的时间点是不会突变的,具体原因待查*2.通过代码判断的夏令时时间段比 实际宣传的少一个小时*/public static void ChangeZone(String time, String srcID, String destID,String pattern) throws ParseException {// 设置默认时区TimeZone zone = TimeZone.getTimeZone(srcID);TimeZone.setDefault(zone);Date date = new SimpleDateFormat(pattern).parse(time);// 设置目标时区TimeZone destzone = TimeZone.getTimeZone(destID);SimpleDateFormat sdf = new SimpleDateFormat(pattern);// 设置要格式化的时区sdf.setTimeZone(destzone);String changTime = sdf.format(date);// 获取目标时区System.out.println("修改时区后" + destzone.getID() + "的时间:" + changTime);}

小结:

虽然存在这2个问题,但是时间并不影响我们代码逻辑,

唯一要注意的是夏令时开始时那6个突变点,是真实的会影响日期的准确性,在数据库进行date比较时,必须要截取日期来比较

 *1.夏令时在结束的时间点是不会突变的,具体原因待查*2.通过代码判断的夏令时时间段比 实际宣传的少一个小时

如果你想解决第一个问题,即在夏令时结束的时候,也让其时间突变,

参考我的另外一篇文章:

http://blog.csdn.net/u011165335/article/details/76636296

java夏令时问题呈现相关推荐

  1. java 夏令时 容器 问题,Java夏令时有关问题

    Java夏令时问题 操作系统不使用 UTC 时间的情况下,操作系统会使用系统记录的夏令时跳变时间点自动进行夏令时切换. suse11 系统在 cd /usr/share/zoneinfo 中有所有时区 ...

  2. Java夏令时导致的问题

    Java夏令时导致的问题 一.查询报错提示 报错提示: HOUR_OF_DAY: 0 -> 1 二.问题原因 通过网上查找资料得知,是中国有一段时间实施过夏令时导致的 1986-1991年 , ...

  3. java 判断是否夏令时_确定指定日期的Java夏令时(DST)是否处于活动状态

    我有一个Java类,它占用一个位置的纬度/经度,并在夏时制开启和关闭时返回GMT偏移量.我正在寻找一个简单的方法来确定Java如果当前日期是在夏令时间,所以我可以应用正确的偏移量.目前,我只对美国时区 ...

  4. java夏令时_java-时间处理夏令时冬令时跨时区问题处理

    作为一个成熟的编程语言,java自然有一堆方法来解决的时间的问题.有的时候我们会因为对java一些内置的api不是太熟悉,对某个场景不熟悉,导致遇到了棘手的问题.比如这个场景夏令时和冬令时 夏令时和冬 ...

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

    一.问题描述 前段时间遇到一个很神奇且费解的问题,程序将用户的生日从日期类型转为string类型时,竟然莫名其妙的少了一天,具体表现为存在数据库的19900916这个日期,取出到程序后做转换为字符串的 ...

  6. java 夏令时标志_夏令时随绝对日期而变化

    要了解时区结构,有助于在以下键下查看Windows注册表: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\ 让我们看一下您提 ...

  7. Java夏令时导致的时间问题

    1986年至1991年,中华人民共和国在全国范围实行了六年夏令时,每年从4月中旬的第一个星期日2时整(北京时间)到9月中旬第一个星期日的凌晨2时 整(北京夏令时) 我们可以看出在中国的夏令时区间内,因 ...

  8. 全面理解java内存模型_深入理解Java内存模型(八)——总结

    处理器内存模型 顺序一致性内存模型是一个理论参考模型,JVM和处理器内存模型在设计时通常会把顺序一致性内存模型作为参照.JVM和处理器内存模型在设计时会对顺序一致性模型做一些放松,因为如果完全按照顺序 ...

  9. java文件流插入数据库_使用Java流查询数据库

    java文件流插入数据库 在本文中,您将学习如何编写纯Java应用程序,这些应用程序能够处理现有数据库中的数据,而无需编写一行SQL(或类似的语言,例如HQL),而无需花费数小时将所有内容放在一起. ...

  10. Java基础08 继承

    继承(inheritance)是面向对象的重要概念.继承是除组合(composition)之外,提高代码重复可用性(reusibility)的另一种重要方式.我们在组合(composition)中看到 ...

最新文章

  1. VMware下Windows2003R2虚拟机磁盘扩容方法
  2. 16位灰度数据成像_16位 250M双通道PCI数据采集卡 FCFR-PCI9808
  3. 部署zabbix企业监控平台
  4. bio阻塞的缺点_java 中的 BIO/NIO/AIO 详解
  5. sigar如何获取linux的buffer内存,Linux 下使用Sigar 获取内存信息
  6. 京东:网传通过 Bug 抢茅台是假消息;罗永浩回应带货价格非「全网最低」;Rust 文档团队解散 | 极客头条...
  7. [摘自MSDN] ASP.Net2.0学习 [1] 母版页 7 : 母版页和内容页中的事件
  8. OpenSSL 1.1.1 国密SM2 SM3 SM4 SM9 ZUC EEA3 EIA3 SM2 +SM3签名 源码 Demo 下载 OpenSSL iOS端库下载
  9. cimiss数据_中国气象数据网
  10. VMware VCenter Converter Standalone 6.2.0下载地址
  11. Vue项目使用file-saver将html转word文件、把html内容下载保存导出到本地生成doc文件包括图片:前端下载利器FileSaver
  12. 树莓派GPIO 基础(一)
  13. 主成分分析 PCA 线性判别分类LDA
  14. iPhone 15 高端版本万元起步;华为授权 OPPO 使用其 5G 技术;DeepMind 推出 AI 编剧|极客头条...
  15. 远程连接华为云服务器上的MySQL
  16. 使用代码的当前SVN版本构建项目build版号
  17. SSL集训 2021.07.16 提高B组 T1 下棋【博弈论】
  18. java说课_Java说课演示稿.ppt
  19. 自制社交门户网站的用户等级表
  20. Drools(8):WorkBench使用

热门文章

  1. 大咖直播 | 大连理工赵纪军教授:人工智能算法用于团簇研究和势函数拟合
  2. linux编译n2n v2,在centos下安装n2n服务器
  3. AiHi+翼次元学院儿童自然感知实践“几米小甜田”+中韧开智“优慧码”| Wit++
  4. Android音频播放器
  5. Android中实现微信分享的功能
  6. 测试网站速度简单方法
  7. OIer__ZLY__OI计划
  8. 金山词霸2009sp3 (解决字典消失、屏幕不能取词问题)
  9. 珍大户《认知世界的经济学》学习笔记 -- 第17课 影响消费者的因素,更新时间2021年03月18日21:53:57
  10. 北京计算机暑期培训,北京暑期计算机培训心得体会.doc