如何在Java中格式化ISO-8601

我试图从标准ISO 8601格式2014-09-11T21:28:29.429209Z转换为一个不错的MMM d yyyy hh:mm z格式,但是我当前的代码失败了。

 public void setCreatedAt( String dateTime ) { LocalDate newDateTime = LocalDate.parse(dateTime); try { DateTimeFormatter format = DateTimeFormatter.ofPattern("MMM d yyyy hh:mm az"); createdAt = newDateTime.format(format); } catch (Exception e) { } } 

我从api收到时间和日期。

java.time.LocalDate是“ISO- java.time.LocalDate ,例如2007-12-03”,因此那里没有足够的信息。 请改用java.time.ZonedDateTime

此外,吞咽这样的例外使得排除故障变得更加困难。 当您不打算处理exception时,要么根本不捕获它,请捕获并重新抛出它包装在RuntimeException中或至少记录它( e.printStackTrace()或类似的)。

TL;博士

 Instant.parse( "2014-09-11T21:28:29.429209Z" ) .atZone( ZoneId.of( "Asia/Kolkata" ) ) .format( DateTimeFormatter.ofPattern("MMM d uuuu hh:mm az" , Locale.US ) ) 

请参阅IdeOne.com上的此代码 。

细节

Jakber的答案将在技术上起作用,但具有误导性。

ZonedDateTime用于时区

ZonedDateTime意味着具有指定的时区,例如America/MontrealPacific/Auckland

但是这个输入字符串缺少时区。 Z的结尾是Zulu缩写,意思是UTC,换句话说,是从零时的偏移+00:00

时区是特定区域的偏移的历史集合,具有即将发生的对诸如夏令时(DST)等exception的偏移的更改的规则。

Instant

输入字符串最好解析为Instant ,它表示时间轴上始终以UTC为单位的时刻。 此类直接以该特定标准ISO 8601格式解析此类字符串,因此无需格式化模式。

 Instant instant = Instant.parse( "2014-09-11T21:28:29.429209Z" ); 

调整到时区

您可以调整到时区以获取ZonedDateTime

 ZoneId z = ZoneId.of( "Asia/Kolkata" ) ; ZonedDateTime zdt = instant.atZone( z ); 

生成字符串

要以与输入相同的格式生成字符串,只需调用Instant::toString()

 String output = instant.toString() ; 

对于使用区域的挂钟时间的自定义格式,请将DateTimeFormatter与自定义格式设置模式一起使用。 和你的ZonedDateTime 。 作为一个好习惯,请始终在翻译中指定用于人类语言的所需区域设置和格式化中的文化规范。

 DateTimeFormatter f = DateTimeFormatter.ofPattern("MMM d uuuu hh:mm az" , Locale.US ); String output = zdt.format( f ); 

关于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等。