调用“new Date(long)”会导致“Jan 01 01:00:00 CET 1970”?

时间:2010-04-08 14:16:58

标签: java date datetime timezone utc

Java doc描述了构造函数Date(long date)使用自1970年1月1日00:00:00 GMT以来的给定毫秒时间值构造Date对象

当我new Date(0)时,日期是1月01日 01:00:00 CET 1970

我不知道为什么从01h开始

3 个答案:

答案 0 :(得分:4)

它显示凌晨1点,因为你比格林尼治标准时间提前了一个小时。日期实例只是自1970年00:00:00 GMT 以来的毫秒数的计数器。从你提前一小时开始,当你的时代发生时,实际上是凌晨1点。

Date实例只是将其toString()方法格式化为使用系统的时区。如果要使用其他区域打印日期,请使用DateFormat实例。

答案 1 :(得分:3)

这是因为您在欧洲时区(CET)中显示日期时间(使用Date对象的毫秒数)使用GMT。

答案 2 :(得分:0)

TL;博士

Instant.now()  // Current moment in UTC.

详细

Nichols的答案是正确的,但过时了。

  • 您所在的时区比该日期的UTC早一个小时,因此您所在区域的UTC午夜时间是凌晨1点。
  • 现在您应该使用 java.time 类,例如Instant而不是Date

避免遗留类

避免使用 java.time 类取代的麻烦的旧日期时间类。

遗留类的许多问题包括:toString方法在生成表示对象值的字符串时动态应用JVM的当前默认时区的设计选择不佳。 Date实际上代表UTC的时刻。完全避免尴尬的课程。如有必要,可以通过添加到旧类的新方法在旧版和现代类之间进行转换。

UTC 的

Instant

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

Instant instant = Instant.now() ;  // Current moment in UTC.
  

instant.toString():2018-02-11T21:07:02.315283Z

如果您想要 java.time 类使用的纪元参考时刻,即UTC中1970年的第一时刻,请使用预定义常量:Instant.EPOCH

  

Instant.EPOCH.toString():1970-01-01T00:00:00Z

OffsetDateTime

如果您需要更多灵活性,例如以其他格式生成字符串,请使用常量InstantOffsetDateTime对象转换为ZoneOffset.UTC

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;

ISO 8601

将日期时间值作为文本进行交换时,请使用标准ISO 8601格式。它们的设计易于通过机器解析,同时也易于被不同文化的人阅读。

生成/解析字符串时, java.time 类默认使用标准的ISO 8601格式。因此无需指定格式化模式。

时区,ZonedDateTime

如果您希望通过镜头看到其他地区的人使用的挂钟时间相同的时刻,请应用时区(ZoneId)来获取ZonedDateTime个对象。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTISTCET之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的( !)。

ZoneId z = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
  

zdt.toString():2018-02-11T22:07:02.315283 + 01:00 [欧洲/巴黎]

让我们看一下同一时区的 java.time 纪元参考时刻。

ZonedDateTime zdtEpochParis = Instant.EPOCH.atZone( z ) ;
  

zdtEpochParis.toString():1970-01-01T01:00 + 01:00 [欧洲/巴黎]

再次,对于另一个时区。

ZonedDateTime zdtEpochMontreal = Instant.EPOCH.atZone( ZoneId.of( "America/Montreal" ) ) ;
  

zdtEpochMontreal.toString():1969-12-31T19:00-05:00 [美国/蒙特利尔]

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

如果JDBC driver符合JDBC 4.2或更高版本,您可以直接与数据库交换 java.time 对象。不需要字符串或java.sql。* classes。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore