关于上一篇https://blog.csdn.net/u011165335/article/details/78924498
介绍了中国以及美国等的夏令时的特点:
*1.夏令时在结束的时间点是不会突变的
*2.通过代码可以知道实际的夏令时时间段比 宣传的少一个小时
系统时区在:注册表
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\China Standard Time

先回顾一下之前的6个突变点:
环境jdk6

package com.ysy;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import java.util.TimeZone;import org.junit.Test;public class Demo {// 比如1986年的夏令时时间,从代码来看,是从1986-05-04 00:00:00到1986-09-13 22:59:59@Testpublic void test4() throws Exception {SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));TimeZone zone = TimeZone.getDefault();System.out.println(zone);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");//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("===1989-04-16 00:00:00实际时间=====" + sf.parse("1989-04-16 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个时间点发生加1个小时的变化:
1986-05-04 00:00:00实际时间=====1986-5-4 1:00:00
1987-04-12 00:00:00实际时间=====1987-4-12 1:00:00
1988-04-10 00:00:00实际时间=====1988-4-10 1:00:00
1989-04-16 00:00:00实际时间=====1989-4-16 1:00:00
1990-04-15 00:00:00实际时间=====1990-4-15 1:00:00
1991-04-14 00:00:00实际时间=====1991-4-14 1:00:00
上面出现,这种情况,说明系统的时区是Asia/Shanghai
那么如果不让时间变化?
java.util.TimeZone类中getDefault方法的源代码显示,它最终是会调用sun.util.calendar.ZoneInfo类的getTimeZone 方法。这个方法为需要的时间区域返回一个作为ID的String参数。这个默认的时间区域ID是从 user.timezone (system)属性那里得到。如果user.timezone没有定义,它就会尝试从user.country和java.home (System)属性来得到ID。 如果它没有成功找到一个时间区域ID,它就会使用一个”fallback” 的GMT值。换句话说, 如果它没有计算出你的时间区域ID,它将使用GMT作为你默认的时间区域。
win对应jre\lib\zi
所以最关键的是设置好user.timezone即可;
如何设置,可以通过jvm参数设置或者System.setProperty

查看user.timezone
System.out.println(System.getProperty(“user.timezone”));
在jdk6,7输出的时区是空的;jdk8的user.timezone可以直接获取到系统时区;

所以只要在jvm设置 -Duser.timezone=GMT+8就可以了;
但是如果有多台服务器,一个设置了GMT+8,一个没设置,还是原来的Asia/Shanghai;那么2台机子的时间传输会发生时间的转换;

下面说的是模拟这种转换:

情况1:win系统的默认时区为Asia/Shanghai;
然后你设置了TimeZone.setDefault(TimeZone.getTimeZone(“GMT+8”));类似你在jvm设置了GMT+8
那么现在一个时间 比如1990-04-17 00:00:00 ,这个时间正处在夏令时时间;
当你设置了GMT+8时区后,它认为正确的显示时间应该是减一个小时,即1990-04-16 23:00:00;
怎么证明?
你可以在截图的里面,把VM参数该为: -Duser.timezone=Asia/Shanghai
然后设置TimeZone.setDefault(TimeZone.getTimeZone(“GMT+8”)),
即可以印证;

===在夏令时1986-05-18 00:00:00实际时间=====1986-5-17 23:00:00
===在夏令时1987-06-17 00:00:00实际时间=====1987-6-16 23:00:00
===在夏令时1988-07-14 00:00:00实际时间=====1988-7-13 23:00:00
===不在夏令时1988-09-11 00:00:00实际时间=====1988-9-11 0:00:00

同理情况2:如win系统的默认时区为GMT+8;
然后你设置了TimeZone.setDefault(TimeZone.getTimeZone(“Asia/Shanghai”));
那么现在一个时间,比如1990-04-17 00:00:00,这个时间对于GMT+8而言,没有夏令时概念;
当你设置了Asia/Shanghai这个时区后,(相当于带有夏令时的东八区),此时会加一个小时,因为对于Asia/Shanghai而言,刚好在夏令时时间内! 于是实际显示为:1990-04-17 01:00:00;
这里代码演示如下:

这里假设win系统的默认时区为GMT+8;
private void test() throws ParseException {SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));TimeZone zone = TimeZone.getDefault();System.out.println(zone);// 夏令时开始时间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("===1989-04-16 00:00:00实际时间=====" + sf.parse("1989-04-16 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());// 夏令时结束时间System.out.println("===1986-09-13 23:00:00实际时间=====" + sf.parse("1986-09-13 23:00:00").toLocaleString());System.out.println("===1987-09-12 23:00:00实际时间=====" + sf.parse("1987-09-12 23:00:00").toLocaleString());System.out.println("===1988-09-10 23:00:00实际时间=====" + sf.parse("1988-09-10 23:00:00").toLocaleString());System.out.println("===1989-09-16 23:00:00实际时间=====" + sf.parse("1989-09-16 23:00:00").toLocaleString());System.out.println("===1990-09-15 23:00:00实际时间=====" + sf.parse("1990-09-15 23:00:00").toLocaleString());System.out.println("===1991-09-14 23:00:00实际时间=====" + sf.parse("1991-09-14 23:00:00").toLocaleString());上面是已知的夏令时开始和结束时间打印下面几个时间:System.out.println("===在夏令时1986-05-18 00:00:00实际时间=====" + sf.parse("1986-05-18 00:00:00").toLocaleString());System.out.println("===在夏令时1987-06-17 00:00:00实际时间=====" + sf.parse("1987-06-17 00:00:00").toLocaleString());System.out.println("===在夏令时1988-07-14 00:00:00实际时间=====" + sf.parse("1988-07-14 00:00:00").toLocaleString());System.out.println("===不在夏令时1988-09-11 00:00:00实际时间=====" + sf.parse("1988-09-11 00:00:00").toLocaleString());}

可以发现:跟预测的一样,在夏令时的加1,不在的不变
===在夏令时1986-05-18 00:00:00实际时间=====1986-5-18 1:00:00
===在夏令时1987-06-17 00:00:00实际时间=====1987-6-17 1:00:00
===在夏令时1988-07-14 00:00:00实际时间=====1988-7-14 1:00:00
===不在夏令时1988-09-11 00:00:00实际时间=====1988-9-11 0:00:00

情况3:如win系统的默认时区为GMT+8;
然后你设置了TimeZone.setDefault(TimeZone.getTimeZone(“GMT+8”));那么时区一致,时间不会变化;

上面演示的就是类似2台机子时区不一致的情况;
jvm设置对机子的设置是可以直接修改user.timezone,没问题的;
让多台机子保持统一就可以了;

如果是linux,也可以修改clock文件;

java 夏令时jvm设置问题相关推荐

  1. java虚拟机MyEclipse_Eclipse和MyEclipse运行环境java虚拟机jvm设置,自己设置jre

    Eclipse运行环境java虚拟机jvm设置,自己设置jre 浅谈Eclipse寻找JVM(JRE)的顺序机制 Eclipse也是一个普通的Java程序,因此必须有一个JRE做为运行环境. 如果你的 ...

  2. java:jvm参数设置

    java:jvm参数设置 1 前言 jvm参数设置后,可通过System.getProperties()或者System.getProperty("jdbc.drivers")来获 ...

  3. java 启动内存参数_请问该如何设置Java虚拟机JVM启动内存参数?

    jps(JVM Process Status Tool):JVM机进程状况工具 用来查看基于HotSpot JVM里面所有进程的具体状态, 包括进程ID,进程启动的路径等等.与unix上的ps类似,用 ...

  4. 形式参数内存在哪java_深入浅出Java中JVM内存管理

    原标题:深入浅出Java中JVM内存管理 Java岗位面试,JVM是对程序员基本功考察,通常会问你对JVM了解吗?可以分几部分回答这个问题,首先JVM内存划分 | JVM垃圾回收的含义 | 有哪些GC ...

  5. 深入理解Java虚拟机——JVM类加载机制(类加载过程和类加载器)

    一.什么是类加载机制? 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 二.类加载的时机 类 ...

  6. [java] 虚拟机(JVM)底层结构详解[转]

    [java] 虚拟机(JVM)底层结构详解[转] 本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 在以前的博客里面,我们介绍了在java领 ...

  7. 深入理解java虚拟机JVM(上)

    深入理解java虚拟机JVM(上) 链接:https://pan.baidu.com/s/1c6pZjLeMQqc9t-OXvUM66w 提取码:uwak 复制这段内容后打开百度网盘手机App,操作更 ...

  8. Java虚拟机JVM的内存管理

    Java虚拟机JVM的内存管理 关键词 一.JVM整体架构 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 名称 作用 特征 配置参数 异常 程序计数器 ...

  9. 【读书笔记】实战JAVA虚拟机JVM故障诊断与性能优化 读书笔记

    文章目录 1.概述 1.1 **第一章:初探java虚拟机** 1.2 认识java虚拟机的基本结构 1.3 常用Java虚拟机参数 1.4 垃圾回收器 1.5 垃圾收集器以及内存分配 1.6 性能监 ...

  10. java查看jvm内存使用情况

    java查看jvm内存使用情况 (2012-03-22 15:50:54) 标签: jvm 内存 虚拟机 分配 it java.lang.Runtime类提供了查看当前JVM内存的使用情况.每个jav ...

最新文章

  1. ubuntu 大小写指示的小工具
  2. 动态分辨率是什么意思_什么是1080p、2k、4k?视频基础参数解释
  3. 二十四、深入Python多线程和多进程
  4. python包管理工具 ports_MacPorts安装使用Python/pip
  5. c# 定位内存快速增长_CTF丨Linux Pwn入门教程:针对函数重定位流程的相关测试(下)...
  6. 大家都为什么考博?采访了12名考生,发现最主要原因竟是这个
  7. 对于新安装的MySQL如何提升MySQL的安全级别
  8. Nginx 架构——【核心流程+模块介绍】
  9. Android菜鸟的成长笔记(16)——Service简介
  10. 算法第四版C++算法实现全集
  11. python爬虫可以找种子吗_python3爬取torrent种子链接实例
  12. 数据库表及字段命名规范
  13. matlab不能radon变换,Radon变换的理解
  14. android手机设置固定dns,手机怎么设置dns 手机设置dns方法【详解】
  15. 【阿里云IoT+YF3300】9.快速开发modbus设备驱动
  16. Excel解析easyexcel工具类
  17. JPEG压缩算法详解(转载)
  18. 安卓Android手机汽车租赁系统app毕业设计
  19. 7 - 6 复数类的定义
  20. 实用小工具 -- 在线查看别人网站流量

热门文章

  1. A股数据day级前复权数据下载与存储
  2. 速卖通奇门+聚石塔流程
  3. Oracle、聚石塔
  4. gwt 同步和异步_使用GWT和RESTful Web服务构建动态的组织树
  5. Xilinx Xio控制sdr sdram
  6. 潇洒郎:Ten-fold-cross validation- Naïve Bayes Classifier 十字交叉验证-贝叶斯分类器 Python实现
  7. you-get遇到的坑
  8. m苹果放n篮子_M个相同苹果放到N个相同篮子里有多少种放法
  9. gnome 3 初见
  10. 《沉思录卷一》闪耀在私人生活圈的品质