我在UTC时区有一台Linux机器。
[user@test packages]$ date +'%:z %Z'
+00:00 UTC
运行cat /etc/localtime
似乎也表明我的计算机处于UTC时区;
[user@test ~]$ cat /etc/localtime
f2UTCTZif2UTC
UTC0
但是,在Java 1.7下运行tomcat的应用程序中调用logger.info(new Date())
会返回类似Mon Oct 28 01:51:39 HDT 2019
这很奇怪,因此我创建了一个简单的Java程序进行测试:
import java.util.Date;
class Test
{
public static void main (String args[])
{
Date dt = new Date();
System.out.println(dt);
}
}
编译并运行
[user@test]$ /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.211.x86_64/bin/javac Test.java
[user@test]$ /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.211.x86_64/bin/java Test
Mon Oct 28 02:08:49 HDT 2019
我的问题是为什么我的Linux实用程序以UTC格式返回日期,而我的Java应用却以HDT格式返回日期(我什至都不知道HDT是什么)。
由于我要维护的应用程序是旧版应用程序,因此我无法使用Joda Time或升级到Java8或更高版本,因为这将导致大量代码更改。
答案 0 :(得分:2)
我终于可以通过以下操作对其进行修复:
ln -fs /usr/share/zoneinfo/UTC /etc/timezone
和/etc/sysconfig/clock
在读完https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6456628
之后,我想到了/etc/sysconfig/clock
答案 1 :(得分:1)
请勿使用旧版类Date
。
Instant.now()
ZonedDateTime.now( ZoneId.of( "Pacific/Honolulu" ) )
2020-02-18T05:28:11.146726Z
2020-02-17T19:28:11.146726-10:00 [太平洋/火奴鲁鲁]
首先,您应该知道您的java.util.Date
实际上是UTC时刻,但是它的toString
方法在生成文本时会动态应用JVM当前的默认时区。很混乱。 从不使用此类的的众多原因之一。
Date
,Calendar
和其他传统的日期时间类在几年前被JSR 310所采用的 java.time 所取代。
使用 java.time 类,您可以轻松编写不依赖默认时区的代码。您可以明确指定所需的UTC偏移量或时区,无论是UTC本身(零小时-分钟-秒的偏移量)还是time zone like Pacific/Honolulu
。
如果要使用UTC跟踪时刻,请使用Instant
。
Instant instant = Instant.now() ;
Instant::toString
方法以标准ISO 8601格式生成文本。该标准定义的格式是为数据交换而设计的。
String output = instant.toString() ;
输出:2020-02-18T05:28:11.146726Z
最后的Z
表示UTC,并发音为“ Zulu”。
如果您想在夏威夷人使用的挂钟时间看到同一时刻,请应用ZoneId
以获得ZonedDateTime
。
请勿使用2-4个字母的缩写,例如HDT
或EST
或IST
,因为它们不是真正的时区,不是标准化的,也不是甚至唯一的(!)。
以Continent/Region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。
ZoneId z = ZoneId.of( "Pacific/Honolulu" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
ZonedDateTime::toString
方法通过在时区的名称后面加上方括号来明智地扩展ISO 8601格式。
String output = zdt.toString() ;
请参阅此code run live at IdeOne.com。
outputZdt:2020-02-17T19:28:11.146726-10:00 [太平洋/火奴鲁鲁]
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
要了解更多信息,请参阅Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规范为JSR 310。
Joda-Time项目(现在位于maintenance mode中)建议迁移到java.time类。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?