将ISO 8601日期转换为标准字符串格式

时间:2015-02-05 19:33:37

标签: java jodatime iso8601

我正在尝试将有效的ISO 8601字符串转换为一致的格式,以便可以使用简单的字典顺序进行排序和搜索。

我的应用程序可以使用以下任何格式接收日期/时间,例如:

2015-02-05T02:05:17.000+00:00
2015-02-05T02:05:17+00:00
2015-02-05T02:05:17Z

这些都代表相同的日期/时间,我想将它们全部转换为规范的存储形式,比如说:

2015-02-05T02:05:17.000Z

我的第一个想法是使用Converting ISO 8601-compliant String to java.util.Date中的技术解析它们,然后转换回所需的字符串,但在处理不太精确的日期/时间时会出现故障,例如:

2015-02-05T02:05:17Z
2015-02-05T02:05Z
2015-02-05Z
2015-02Z
2015Z

应保留这些时间的不精确性。它们不应转换为:

2015-02-05T00:00:00.000Z

我看过Java 8和Joda-Time,但他们似乎想要将所有内容视为特定时间点,并且不能模拟不精确的性质或部分日期/时间。

更新:

使用Java 8,我可以这样做:

OffsetDateTime dateTime = OffsetDateTime.parse("2015-02-05T02:05:17+00:00");
System.out.println(dateTime.toString());

给了我:

2015-02-05T02:05:17Z

这就是我想要的,但是:

OffsetDateTime dateTime = OffsetDateTime.parse("2015-02-05T02:05:17.000+00:00");
System.out.println(dateTime.toString());

也给了我:

2015-02-05T02:05:17Z

请注意,java已经抛弃了毫秒精度。指定000与未指定任何内容相同,这似乎不太正确。

2 个答案:

答案 0 :(得分:7)

在Java 8中,如果字符串为 ISO 8601 格式,则可以在String上使用LocalDate.parse()LocalDateTime.parse()而不为其提供模式

  

parse(),   从文本字符串(如2007-12-03)获取LocalDate的实例。   该字符串必须表示有效日期并使用进行解析   DateTimeFormatter.ISO_LOCAL_DATE。

  

DateTimeFormatter.ISO_LOCAL_DATE,   这将返回一个能够格式化和解析的不可变格式化程序   ISO 8601

例如,

String strDate = "2015-08-04";
LocalDate aLD = LocalDate.parse(strDate);
System.out.println("Date: " + aLD);

String strDatewithTime = "2015-08-04T10:11:30";
LocalDateTime aLDT = LocalDateTime.parse(strDatewithTime);
System.out.println("Date with Time: " + aLDT);

给出,

Date: 2015-08-04
Date with Time: 2015-08-04T10:11:30

<强>更新

你的日期,即"2015-02-05T02:05:17.000+00:00"只会在零时抛出零 它们都是零,如果纳秒的值不是零,那么它会显示得很好,但是,如果你想显示零,那么你只需添加if/else块并在你的日期附加零{{ 1}}你的纳秒数为零(if),yourdate.getNano()==0按原样打印,

else

会给,

String dateTimestr = "2015-02-05T02:05:17.000+00:00";

OffsetDateTime dateTime = OffsetDateTime.parse(dateTimestr);

if ((dateTime.getNano() == 0) && (dateTimestr.length() > 25 ))
    System.out.println(dateTime.toLocalDateTime() + ".000Z");

else
    System.out.println(dateTime.toString());

将日期更改为,

2015-02-05T02:05:17.000Z

给出,

String dateTimestr = "2015-02-05T02:05:17+00:00";

将日期更改为,

2015-02-05T02:05:17Z

给出,

String dateTimestr = "2015-02-05T02:05:17.100+00:00";

将其更改为,

2015-02-05T02:05:17.100Z

给出,

String dateTimestr = "2015-02-05T02:05:17Z";

答案 1 :(得分:1)

您必须明白,精确度的保存只能在文本空间中进行,而不能在值空间中进行。因此,可以以文本方式表示不同的精度(请参阅您的输入),但不能在值对象(此处为OffsetDateTime类型)中表达。 Latter仅存储日期时间值,但不存储任何额外的精度信息。如果你真的想要实现这个目标,那么你别无选择,只能将自己的类编写为OffsetDateTime的包装和精度(表示为ChronoUnit - 枚举)。

否则,如果您始终希望保留输出的精度(以毫秒为单位),则不应使用toString() - 方法,而应使用专用格式化程序。在Java-8中,这将是:

OffsetDateTime odt = OffsetDateTime.parse("2015-02-05T02:05:17+00:00");
String dateTimeWithMilliSecondPrecision = 
  odt.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxxx"));
System.out.println(dateTimeWithMilliSecondPrecision);
// output: 2015-02-05T02:05:17.000+00:00