Java:如何以ISO 8601 SECOND格式获取当前日期

我需要在ISO 8601中获得SS毫秒HH:MM时区的当前日期

完成日期加上小时,分钟,秒和小数秒:YYYY-MM-DDThh:mm:ss.sTZD(例如1997-07-16T19:20:30.45 + 01:00

请参阅: http : //www.w3.org/TR/NOTE-datetime

我尝试了不同的方法,但我无法得到正确的毫秒和时区数字:

DateFormat df=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSZZ"); df.setTimeZone(TimeZone.getTimeZone("UTC")); df.format(new Date()); 

JAVA结果: 2012-11-24T21:19:27。 758 + 0000

Apache结果: 2012-11-24T21:19:27。 758 + 00:00 (Apache Commons FastDateFormat)

实际上JDK中有一个类来处理ISO8601的解析和格式化:

 import javax.xml.bind.DatatypeConverter; DatatypeConverter.printDateTime(new GregorianCalendar()) //2012-11-24T22:42:03.142+01:00 

TL;博士

当前时刻,UTC

使用java.time.Instant以分辨率捕获当前时刻,精确到纳秒。

 Instant.now() // Capture the current moment in UTC, with a resolution as fine as nanoseconds. Typically captured in microseconds in Java 9 and later, milliseconds in Java 8. .toString() // Generate a `String` representing the value of this `Instant` in standard ISO 8601 format. 

2018-01-23T12:34:56.123456Z

最后的Z

  • 是指UTC ,
  • 相当于+00:00 偏移 ,
  • 发音为“Zulu”,和
  • 由ISO 8601标准以及军事等其他领域定义。

当前时刻,特定偏移量

如果出于某种不寻常的原因,您必须调整到UTC的特定偏移量 ,请使用OffsetDateTime ,传递ZoneOffset

 OffsetDateTime.now( // Capture the current moment. ZoneOffset.ofHours( 1 ) // View the current moment adjusted to the wall-clock time of this specific offset-from-UTC. BTW, better to use time zones, generally, than a mere offset-from-UTC. ) .toString() // Generate a `String` in standard ISO 8601 format. 

2018-07-08T21:13:10.723676 + 01:00

当前时刻,截断为毫秒

对于毫秒分辨率, 截断 。 通过ChronoUnit枚举指定分辨率。

 OffsetDateTime.now( ZoneOffset.ofHours( 1 ) ) .truncatedTo( // Lop off finer part of the date-time. We want to drop any microseconds or nanoseconds, so truncate to milliseconds. Using the immutable objects pattern, so a separate new `OffsetDateTime` object is generated based on the original object's values. ChronoUnit.MILLIS // Specify your desired granularity via `ChronoUnit` enum. ) .toString() 

2018-07-08T21:13:10.723 + 01:00

java.time

在解析或生成日期时间值的文本表示时,Java 8及更高版本中内置的java.time框架将默认使用ISO 8601 。

Instant是UTC时间轴上的一个时刻,分辨率为纳秒 。

 Instant instant = Instant.now(); 

在Java 8中以Java毫秒的分辨率捕获当前时刻,在Java 9及更高版本中,通常分辨率为微秒,具体取决于主机硬件时钟和OS的能力。 如果您特别需要毫秒分辨率,请截断任何微秒或纳秒。

 Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS ) ; 

但是你想要一个特定的UTC偏移量 。 因此,请指定ZoneOffset以获取OffsetDateTime

 ZoneOffset offset = ZoneOffset( "+01:00" ); OffsetDateTime odt = OffsetDateTime.ofInstant( instant , offset ); 

再次,如果您特别需要毫秒分辨率而不是微秒或纳秒,则截断。

 odt = odt.truncatedTo( ChronoUnit.MILLIS ) ; // Replace original `OffsetDateTime` object with new `OffsetDateTime` object based on the original but with any micros/nanos lopped off. 

要生成ISO 8601字符串,只需调用toString

 String output = odt.toString(); 

转储到控制台。 在输出中注意小时如何向前滚动作为+01:00偏移的调整,甚至在午夜滚动,所以日期从第12变为第13。

 System.out.println ( "instant: " + instant + " | offset: " + offset + " | odt: " + odt ); 

时间:2016-04-12T23:12:24.015Z | 偏移量:+01:00 | odt:2016-04-13T00:12:24.015 + 01:00

顺便说一句,最好使用一个时区(如果已知)而不仅仅是一个偏移量。 时区是特定地区人民使用的偏移的过去,现在和未来变化的历史。

在java.time中,这意味着应用ZoneId来获取ZonedDateTime

 ZoneId zoneId = ZoneId.of( "Europe/Paris" ); ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId ); 

或者跳过Instant ,作为快捷方式。

 ZonedDateTime zdt = ZonedDateTime.now( zoneId ) ; 

生成一个String以文本方式表示该ZonedDateTime对象的值。 默认使用的格式是标准的ISO 8601格式,明智地扩展为在方括号中附加区域的名称。

zdt.toString():2018-07-08T22:06:58.780923 + 02:00 [欧洲/巴黎]

对于其他格式,请使用DateTimeFormatter类。


关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

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

要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。

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

从哪里获取java.time类?

  • Java SE 8Java SE 9Java SE 10及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6Java SE 7
    • 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
  • Android的
    • 更高版本的Android捆绑java.time类的实现。
    • 对于早期的Android(<26), ThreeTenABP项目采用ThreeTen-Backport (如上所述)。 请参见如何使用ThreeTenABP ….

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