如何用Java格式化ISO-8601

如何用Java格式化ISO-8601,java,json,Java,Json,我正在尝试从标准格式2014-09-11T21:28:29.429209Z更改为一种不错的MMM d yyy hh:mm z格式,但是我当前的代码失败了 public void setCreatedAt( String dateTime ) { LocalDate newDateTime = LocalDate.parse(dateTime); try { DateTimeFormatter format = DateTimeFormatter.ofPatte

我正在尝试从标准格式
2014-09-11T21:28:29.429209Z
更改为一种不错的MMM d yyy 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接收时间和日期。

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

此外,接受这样的异常会使故障排除变得更加困难。当您不打算处理异常时,或者根本不捕获它,捕获并重新抛出它包装在RuntimeException中,或者至少记录它(
e.printStackTrace()
或类似内容)。

tl;博士 看这个

细节 该方案在技术上可行,但具有误导性

ZoneDateTime
用于时区 A意味着有一个指定的时区,如
美国/蒙特利尔
太平洋/奥克兰

但是这个输入字符串缺少时区。末尾的
Z
Zulu
的缩写,表示UTC,或者换句话说,与UTC的零小时偏移量,
+00:00

时区是特定区域偏移量的历史集合,具有针对异常(例如)偏移量即将发生的更改的规则

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

Instant instant = Instant.parse( "2014-09-11T21:28:29.429209Z" );
适应时区 你可以调整到一个时区,以获得一个时间

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

对于使用地区挂钟时间的自定义格式,请将
DateTimeFormatter
与自定义格式模式一起使用。以及您的
分区日期时间
。作为一个好习惯,在翻译中始终指定人类语言所需的语言环境,并在格式中指定文化规范

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

关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

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

从哪里获得java.time类

  • 然后
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 更高版本的Android捆绑包实现了java.time类

    • 对于早期的Android(@RaminOmrani the“z”2014-09-11T21:28:29.429209Z代表UTC。您是否为此尝试了joda time API???@Bhupi没有理由切换到joda time来解决此问题。事实上,您很可能会看到相同的选择。它成功了!谢谢!我肯定需要处理异常。谢谢您的提示!)还要注意,
      LocalDate
      不能保存时间组件,只能保存日期组件。
      ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
      ZonedDateTime zdt = instant.atZone( z );
      
      String output = instant.toString() ;
      
      DateTimeFormatter f = DateTimeFormatter.ofPattern("MMM d uuuu hh:mm a z" , Locale.US );
      String output = zdt.format( f ); 
      
      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();
          }
      }