Java时间与OS时间不同

Use*_*108 3 java datetime

当我在Unix中打印日期时,它显示UTC时间

[app@host ~]$ date
Thu Sep  6 21:16:07 UTC 2018
Run Code Online (Sandbox Code Playgroud)

当我在同一台计算机上从Java打印日期时

public static void main(String[] args) {
  System.out.println("date=" + new Date());
  System.out.println("date from mills=" + new Date(System.currentTimeMillis()));
  System.out.println(TimeZone.getDefault().getDisplayName());

  Instant instant = Instant.now();
  System.out.println("instant=" + instant);
  System.out.println("instant from mills=" + new Date(instant.toEpochMilli()));
}
Run Code Online (Sandbox Code Playgroud)

打印PST时间

[app@host ~]$ java TimeTest
date=Thu Sep 06 14:17:09 PDT 2018
date from mills=Thu Sep 06 14:17:09 PDT 2018
Pacific Standard Time
instant=2018-09-06T21:17:09.030Z
instant from mills=Thu Sep 06 14:17:09 PDT 2018
Run Code Online (Sandbox Code Playgroud)

Java如何获取PST时区?

此外,回传文件的轮换发生在UTC时间,并且日志文件中打印的时间显示了PST时间。

Bas*_*que 5

tl; dr

仅使用java.time类。

切勿使用Date课堂。

记录时使用UTC。

Instant.now().toString()
Run Code Online (Sandbox Code Playgroud)

2018-01-23T01:23:45.123456Z

细节

堆栈溢出已经解决了很多次。

糟糕的旧式传统日期时间类充斥着糟糕的设计选择。在这些较差的选择中,有Date::toString一种方法的行为是在生成字符串时动态应用JVM的当前默认时区。意图良好,但java.util.Date像一样令人误解的java.time.Instant,代表了UTC的时刻。

今年9月6日,北美大部分地区西海岸的下午2点在UTC同时为晚上9点,在夏令时(DST)期间,UTC的偏移时间比UTC晚7个小时。同一时刻,时间轴上的同一点,不同的时钟时间。

为什么选择PDT?

为什么特别是太平洋夏令时(PDT)?您的JVM始终具有当前的默认时区。显然,您的JVM设置为区域的当前默认值,例如America/Los_Angeles(PDT不是实时区域)。

如何设置默认值取决于您的JVM实现和设置。通常,启动时的JVM会选择主机操作系统的当前默认区域。您可以将参数传递给JVM的启动以指定区域,而不是选择主机OS的默认值。

启动后,JVM内任何应用程序的任何线程中的任何代码都可以随时通过调用更改当前默认时区,TimeZone.setDefault以立即影响该JVM中的所有其他代码。

这意味着您绝不应该依赖当前的默认区域来处理任何重要的事情,因为它的值超出了程序员的控制范围。始终明确指定所需/期望的时区。即使您想使用当前的默认值,也要显式调用ZoneId.systemDefault

额外提示:同上Locale。始终是当前默认值。但是要明确指定而不是隐式依赖默认值。

使用java.time

切勿使用旧的日期类。仅使用java.time类。

记录时,请始终使用UTC。呈现标准ISO 8601格式的文本,如所示Instant::toString

Instant instant = Instant.now() ;
Run Code Online (Sandbox Code Playgroud)

如果您想查看特定地区人们使用的挂钟时间中的这一时刻,请应用时区(ZoneId)以获取ZonedDateTime

ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Run Code Online (Sandbox Code Playgroud)

关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和SimpleDateFormat

现在处于维护模式Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*

在哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多