JDK时区TimeZone与操作系统不一致怎么办

这篇文章主要介绍JDK时区TimeZone与操作系统不一致怎么办,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

创新新互联,凭借10余年的做网站、成都网站制作经验,本着真心·诚心服务的企业理念服务于成都中小企业设计网站有数千家案例。做网站建设,选创新互联

【背景】一台Windows服务器的迁移工作,涉及操作系统、应用以及数据库,其中:
  1.操作系统由Windows Server 2003--->Windows Server 2008
  2.数据库:Oracle 10.2.0.4--->Oracle 11.2.0.3
  3.应用迁移本在本篇博文的讨论范围
 之前方案经过几轮评审,该改进地方修改了多次。测试环境也进行了多次测试。自认为在生产环境变更会一切顺利,万无一失,自信满满,但很快被现实狠狠的抽了一巴掌。经梳理,碰到的问题主要有两个,以下计划分两篇进行总结归纳,若有错误,欢迎各位大神指正。
  服务器迁移完成后,启动定时作业出现了一个异常现象,该作业理应生成T-1日文件不知为何文件变成了T-2日。出现问题的时候,开发人员并不在现场,本着先不麻烦别人的原则。第一反应就是有可能是数据库迁移造成的。
 为排除数据库方面的问题,我们查询了常用时间变量sysdate,systimestamp,localtimestamp以及current_timestamp,发现输出都和自然时间相同。

  1. SELECT sysdate FROM dual;

  2. SYSDATE

  3. -----------------

  4. 20170409 07:56:19

  5. SELECT systimestamp FROM dual;

  6. SYSTIMESTAMP

  7. ---------------------------------------------------------------------------

  8. 09-APR-17 07.56.52.311941 AM +08:00

  9. SELECT localtimestamp FROM dual;

  10. LOCALTIMESTAMP

  11. ---------------------------------------------------------------------------

  12. 09-APR-17 07.59.04.507493 AM

  13. SELECT current_timestamp FROM dual;

  14. CURRENT_TIMESTAMP

  15. ---------------------------------------------------------------------------

  16. 09-APR-17 07.59.17.414758 AM +08:00

  那看来和数据库无关?正在犹豫的时候,再次启动定时作业的时候发现执行结果正确了,生成了T-1日的文件,且文件内容也无异常。奇怪,不过定时作业总算执行正常了,由于有其他事情要忙,这个事情就没有再深入分析。
  悲催的是,第二天问题又重现了,且情况和前一天几乎一样:刚开始作业异常,分析了一段时间,再次重启作业又正常了。什么情况?看来这个不是偶发现象,要仔细深入的研究个明白了。在分析过程我们发现了一个非常有趣的现象:作业若在8点之前执行就会异常,一过8点作业执行正常。难道是时区造成的?不对啊,前面已经查询已经确认了,数据库时区和时间都没问题。为了进一步确认数据库时区正常,还是查看一下dbtimezone变量吧。

点击(此处)折叠或打开

  1. SELECT dbtimezone FROM dual;

  2. DBTIME

  3. ------

  4. +08:00

   基本排查了数据库的原因造成的,作为DBA的我不禁松了一口气。下面的分析可以放松些了,不用提心吊胆啦,哈哈。既然怀疑时区造成的,那看看是不是操作系统的时区问题。但非常遗憾经确认操作系统时区设置也是正确的 :东8区。经过一番确认和排查,始终未发现服务器、数据库参数设置的问题,找开发要代码吧。代码非常简单,截取部分有用内容如下:

点击(此处)折叠或打开

  1. String strCreDate = new java.sql.Date(new java.util.Date().getTime()-86400000).toString();

   具体生成T-1日还是T-2日的文件,由strCreDate变量决定的。那看来变量strCreDate的值有问题。我们分别做了一组实验:8点前strCreDate的值为T-2,但8点后该值就变成了T-1.为清楚的看到JDK时区情况,写了一个非常简单HelloWorld代码,如下: 

点击(此处)折叠或打开

  1. import java.util.TimeZone;

  2. import java.sql.Date;

  3. public class HelloWorld {

  4.     public static void main(String[] args) {

  5.     System.out.print("当前的默认时区为");

  6.     System.out.println(TimeZone.getDefault());                            //输出当前默认时区 

  7.     final TimeZone zone = TimeZone.getTimeZone("GMT+8");                  //获取中国时区

  8.     TimeZone.setDefault(zone);                                            //设置时区

  9.     System.out.println(TimeZone.getDefault());                            //输出验证 

  10.     }

  11. }

   第一个输出结果为:
JDK时区TimeZone与操作系统不一致怎么办
 第二个输出结果为:
JDK时区TimeZone与操作系统不一致怎么办
    发现了什么了吗?虽然操作系统的时区为东8区,但是jdk获取的时区不是东8区,缺是UTC,因此造成了差8个小时的现象,即8点前作业异常,8点后作业又正常了。问题已经找出来了,就是jdk的问题,解决方案就迎刃而解了。具体办法如下:
 在下面四个目录(Java\jre6\lib\zi\Etc、Java\jre6\lib\zi、Java\jdk1.6.0_18\jre\lib\zi\Etc、Java\jdk1.6.0_18\jre\lib\zi)下找到GMT文件备份一下,然后复制一份GMT-8并重命名为GMT,复制完毕,重新运行一下java程序问题即可解决!
    按照上述方法处理后,再次运行HelloWorld命令,输出正常了。次日观察作业也正常了。至此问题处理完毕。

以上是“JDK时区TimeZone与操作系统不一致怎么办”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注创新互联行业资讯频道!


当前文章:JDK时区TimeZone与操作系统不一致怎么办
转载来于:http://scyanting.com/article/ijcdij.html