java 夏令时jvm设置问题
关于上一篇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设置问题相关推荐
- java虚拟机MyEclipse_Eclipse和MyEclipse运行环境java虚拟机jvm设置,自己设置jre
Eclipse运行环境java虚拟机jvm设置,自己设置jre 浅谈Eclipse寻找JVM(JRE)的顺序机制 Eclipse也是一个普通的Java程序,因此必须有一个JRE做为运行环境. 如果你的 ...
- java:jvm参数设置
java:jvm参数设置 1 前言 jvm参数设置后,可通过System.getProperties()或者System.getProperty("jdbc.drivers")来获 ...
- java 启动内存参数_请问该如何设置Java虚拟机JVM启动内存参数?
jps(JVM Process Status Tool):JVM机进程状况工具 用来查看基于HotSpot JVM里面所有进程的具体状态, 包括进程ID,进程启动的路径等等.与unix上的ps类似,用 ...
- 形式参数内存在哪java_深入浅出Java中JVM内存管理
原标题:深入浅出Java中JVM内存管理 Java岗位面试,JVM是对程序员基本功考察,通常会问你对JVM了解吗?可以分几部分回答这个问题,首先JVM内存划分 | JVM垃圾回收的含义 | 有哪些GC ...
- 深入理解Java虚拟机——JVM类加载机制(类加载过程和类加载器)
一.什么是类加载机制? 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 二.类加载的时机 类 ...
- [java] 虚拟机(JVM)底层结构详解[转]
[java] 虚拟机(JVM)底层结构详解[转] 本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 在以前的博客里面,我们介绍了在java领 ...
- 深入理解java虚拟机JVM(上)
深入理解java虚拟机JVM(上) 链接:https://pan.baidu.com/s/1c6pZjLeMQqc9t-OXvUM66w 提取码:uwak 复制这段内容后打开百度网盘手机App,操作更 ...
- Java虚拟机JVM的内存管理
Java虚拟机JVM的内存管理 关键词 一.JVM整体架构 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 名称 作用 特征 配置参数 异常 程序计数器 ...
- 【读书笔记】实战JAVA虚拟机JVM故障诊断与性能优化 读书笔记
文章目录 1.概述 1.1 **第一章:初探java虚拟机** 1.2 认识java虚拟机的基本结构 1.3 常用Java虚拟机参数 1.4 垃圾回收器 1.5 垃圾收集器以及内存分配 1.6 性能监 ...
- java查看jvm内存使用情况
java查看jvm内存使用情况 (2012-03-22 15:50:54) 标签: jvm 内存 虚拟机 分配 it java.lang.Runtime类提供了查看当前JVM内存的使用情况.每个jav ...
最新文章
- ubuntu 大小写指示的小工具
- 动态分辨率是什么意思_什么是1080p、2k、4k?视频基础参数解释
- 二十四、深入Python多线程和多进程
- python包管理工具 ports_MacPorts安装使用Python/pip
- c# 定位内存快速增长_CTF丨Linux Pwn入门教程:针对函数重定位流程的相关测试(下)...
- 大家都为什么考博?采访了12名考生,发现最主要原因竟是这个
- 对于新安装的MySQL如何提升MySQL的安全级别
- Nginx 架构——【核心流程+模块介绍】
- Android菜鸟的成长笔记(16)——Service简介
- 算法第四版C++算法实现全集
- python爬虫可以找种子吗_python3爬取torrent种子链接实例
- 数据库表及字段命名规范
- matlab不能radon变换,Radon变换的理解
- android手机设置固定dns,手机怎么设置dns 手机设置dns方法【详解】
- 【阿里云IoT+YF3300】9.快速开发modbus设备驱动
- Excel解析easyexcel工具类
- JPEG压缩算法详解(转载)
- 安卓Android手机汽车租赁系统app毕业设计
- 7 - 6 复数类的定义
- 实用小工具 -- 在线查看别人网站流量