我正在尝试将有效的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与未指定任何内容相同,这似乎不太正确。
答案 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