环境之间的时区差异
Posted
技术标签:
【中文标题】环境之间的时区差异【英文标题】:timezone difference between environments 【发布时间】:2018-12-18 13:15:09 【问题描述】:我有一个基于 Spring 的应用程序,它托管在两个环境中:S1 和 S2 - RedHat 服务器上的 tomcat 8 实例。问题是,出于日志记录和持久性目的,它认为 “现在” 的时间各不相同:
它在 S1 上报告正确的时间 S2 休息一小时环境信息:
红帽企业 Linux 服务器 6.9 JVM 版本:1.8 -Duser.timezone=欧洲/柏林 /etc/localtime 对于两种环境都是相同的我编写了简单的调试代码,结果因环境而异:
System.out.println("[TimeZone]TimeZone ID: " + TimeZone.getDefault().getID());
System.out.println("[TimeZone]TimeZone name: " + TimeZone.getDefault().getDisplayName());
Date date = new Date();
LocalDateTime localDate = LocalDateTime.now();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println("[Date]Date and time: " + df.format(date));
System.out.println("[LocalDateTime]Date and time: " + formatter.format(localDate));
df.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
ZonedDateTime zdt = localDate.atZone(ZoneId.of("Europe/Berlin"));
System.out.println("[Date]Date and time in Berlin: " + df.format(date));
System.out.println("[ZonedDateTime]Date and time in Berlin: " + formatter.format(zdt));
结果:
S1
[TimeZone]TimeZone ID: Europe/Berlin
[TimeZone]TimeZone name: Central European Time
[Date]Date and time: 2018-07-10 14:24:52
[LocalDateTime]Date and time: 2018-07-10 14:24:52
[Date]Date and time in Berlin: 2018-07-10 14:24:52
[ZonedDateTime]Date and time in Berlin: 2018-07-10 14:24:52
S2
[TimeZone]TimeZone ID: GMT+01:00
[TimeZone]TimeZone name: GMT+01:00
[Date]Date and time: 2018-07-10 13:29:18
[LocalDateTime]Date and time: 2018-07-10 13:29:18
[Date]Date and time in Berlin: 2018-07-10 14:29:18
[ZonedDateTime]Date and time in Berlin: 2018-07-10 13:29:18
更多诊断信息:
xxx@serv1:~ > ls -l /etc/localtime
-rw-r--r--. 1 root root 2309 Apr 8 2016 /etc/localtime
xxx@serv1:~ > zdump /etc/sysconfig/clock
/etc/sysconfig/clock Fri Jul 20 09:21:01 2018
xxx@serv2:~ > ls -l /etc/localtime
-rw-r--r--. 1 root root 2309 Feb 13 2014 /etc/localtime
xxx@serv2:~ > zdump /etc/sysconfig/clock
/etc/sysconfig/clock Fri Jul 20 09:20:47 2018
您可能已经注意到,尽管设置了 JVM 属性,但 S2 上的应用程序未正确加载 TimeZone。
所以问题是,我如何才能更正 S2 上的应用程序的时间?或者至少,我该如何进一步调查?
【问题讨论】:
他们报告的结果不同。 S1 报告 CET 和 S2 GMT+1 .. 这些是不同的东西... CET 可以是 +1 或 +2 取决于 DST ... GMT+1 总是很好 +1 ... 我假设他们报告相同的 UTC 时间(在一定的误差范围内)。确保另一个盒子上没有任何环境变量覆盖其他设置(或者某些东西可能无法访问?!)。 我的意思是,A 和 B 的输出是相同的,它因环境而异。调试代码作为@PostConstruct
钩子运行。我并不真正精通 linux 管理员 - 我应该看看哪些环境变量?
所以如果理解正确,应用程序 A 正在打印正确的时区,但问题出在 S2 上的应用程序 B 上?我对吗? @用户
肯定是服务器时间/时区问题。
@Deadpool A 正在打印正确的 时间,这发生在 log4j 的日志中,以及在休眠期间持久化期间的数据库中,在设置为 LocalDateTime.now()
的字段中。 B 休息一小时。
【参考方案1】:
看起来像一个简单的问题:
在 S1 上,您已将 Europe/Berlin 设置为时区, 在 S2 上,您已设置 GMT+01:00
您还告诉我们,您的实际日期是 2018-07-10,它位于德国的夏季时间段(从欧洲/柏林 S1 时区提取)。
所以在 S1 时区 Europe/Berlin 根据夏令时(夏令时)在 GMT+01 和 GMT+02 之间变化 - 而在 S2 始终是 GMT+01。
这解释了 S1 和 S2 之间 1 小时的差异。
要解决此问题,您最好将 S2 上的时区也更改为 Europe/Berlin,以便在那里也可以使用自动夏令时。
只能在夏季检测到 1 小时的休息时间,而不能在正常(通常被错误地称为“冬季”)时间内检测到。
【讨论】:
以上是关于环境之间的时区差异的主要内容,如果未能解决你的问题,请参考以下文章
由于 IP 和 SP 之间的时区差异导致的 Spring Saml 安全身份验证问题