如何在Java中格式化ISO-8601

时间:2015-07-08 16:51:54

标签: java json

我正在尝试从标准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 a z");
        createdAt = newDateTime.format(format); 
    }
    catch (Exception e) {
    }

}

我收到api的时间和日期。

3 个答案:

答案 0 :(得分:2)

java.time.LocalDate是“ISO-8601日历系统中没有时区的日期,例如2007-12-03”,因此那里没有足够的信息。请改用java.time.ZonedDateTime

此外,吞噬这样的例外情况会使故障排除更加困难。如果您不打算处理异常,或者根本不捕获它,请捕获并重新抛出它包装在RuntimeException中或至少记录它(e.printStackTrace()或类似的)。

答案 1 :(得分:1)

TL;博士

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

请参阅此code run live at IdeOne.com

详细

Answer by Jakber将在技术上有效,但会产生误导。

ZonedDateTime用于时区

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

但是这个输入字符串没有时区。最后的ZZulu的缩写,表示UTC,换句话说,就是零点小时的偏移量+00:00

时区是特定区域的偏移的历史集合,其中包含即将发生的Daylight Saving Time (DST)等异常偏移更改的规则。

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 a z" , Locale.US );
String output = zdt.format( f ); 

关于 java.time

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

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

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

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

从哪里获取java.time类?

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

答案 2 :(得分:0)

public void setCreatedAt(String dateTime) {
    SimpleDateFormat sdfSource = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
    SimpleDateFormat sdfTarget = new SimpleDateFormat("MMM d yyyy hh:mm a z", Locale.getDefault());
    try {
        Date date = sdfSource.parse(dateTime);
        String createdAt = sdfTarget.format(date);
        Log.e(TAG, "setCreatedAt: createdAt " + createdAt);
    } catch (ParseException e) {
        e.printStackTrace();
    }
}