这篇文章主要介绍JDK时区TimeZone与操作系统不一致怎么办,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
【背景】一台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,发现输出都和自然时间相同。
SELECT sysdate FROM dual;
SYSDATE
-----------------
20170409 07:56:19
SELECT systimestamp FROM dual;
SYSTIMESTAMP
---------------------------------------------------------------------------
09-APR-17 07.56.52.311941 AM +08:00
SELECT localtimestamp FROM dual;
LOCALTIMESTAMP
---------------------------------------------------------------------------
09-APR-17 07.59.04.507493 AM
SELECT current_timestamp FROM dual;
CURRENT_TIMESTAMP
---------------------------------------------------------------------------
09-APR-17 07.59.17.414758 AM +08:00
那看来和数据库无关?正在犹豫的时候,再次启动定时作业的时候发现执行结果正确了,生成了T-1日的文件,且文件内容也无异常。奇怪,不过定时作业总算执行正常了,由于有其他事情要忙,这个事情就没有再深入分析。
悲催的是,第二天问题又重现了,且情况和前一天几乎一样:刚开始作业异常,分析了一段时间,再次重启作业又正常了。什么情况?看来这个不是偶发现象,要仔细深入的研究个明白了。在分析过程我们发现了一个非常有趣的现象:作业若在8点之前执行就会异常,一过8点作业执行正常。难道是时区造成的?不对啊,前面已经查询已经确认了,数据库时区和时间都没问题。为了进一步确认数据库时区正常,还是查看一下dbtimezone变量吧。
点击(此处)折叠或打开
SELECT dbtimezone FROM dual;
DBTIME
------
+08:00
基本排查了数据库的原因造成的,作为DBA的我不禁松了一口气。下面的分析可以放松些了,不用提心吊胆啦,哈哈。既然怀疑时区造成的,那看看是不是操作系统的时区问题。但非常遗憾经确认操作系统时区设置也是正确的 :东8区。经过一番确认和排查,始终未发现服务器、数据库参数设置的问题,找开发要代码吧。代码非常简单,截取部分有用内容如下:
点击(此处)折叠或打开
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代码,如下:
点击(此处)折叠或打开
import java.util.TimeZone;
import java.sql.Date;
public class HelloWorld {
public static void main(String[] args) {
System.out.print("当前的默认时区为");
System.out.println(TimeZone.getDefault()); //输出当前默认时区
final TimeZone zone = TimeZone.getTimeZone("GMT+8"); //获取中国时区
TimeZone.setDefault(zone); //设置时区
System.out.println(TimeZone.getDefault()); //输出验证
}
}
第一个输出结果为:
第二个输出结果为:
发现了什么了吗?虽然操作系统的时区为东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与操作系统不一致怎么办”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。