DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
// time is optional
.optionalStart()
.parseCaseInsensitive()
.appendPattern("[ ]['T']")
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.optionalEnd()
// offset is optional
.appendPattern("[xx]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.toFormatter();
for (String queryParam : new String[] {
"2017-05-05 00:00:00.000+0000",
"2017-05-05 00:00:00.000",
"2017-05-05T00:00:00",
"2017-05-05+0000",
"2017-05-05",
"2017-05-05T11:20:30.643+0000",
"2017-05-05 16:25:09.897+0000",
"2017-05-05 22:13:55.996",
"2017-05-05t02:24:01"
}) {
Instant inst = OffsetDateTime.parse(queryParam, formatter).toInstant();
System.out.println(inst);
}
此代码段的输出是:
2017-05-05T00:00:00Z
2017-05-05T00:00:00Z
2017-05-05T00:00:00Z
2017-05-05T00:00:00Z
2017-05-05T00:00:00Z
2017-05-05T11:20:30.643Z
2017-05-05T16:25:09.897Z
2017-05-05T22:13:55.996Z
2017-05-05T02:24:01Z
我使用的技巧包括:
-
optionalStart
optionalEnd
或在
[]
-
DateTimeFormatter.ISO_LOCAL_TIME
已经处理可选的秒数和秒的分数。
-
用于解析为
OffsetDateTime
parseDefaulting
这是真的。
Date
. 这个
java.util.Date
类已经过时很久了,并且有很多设计问题,所以尽可能避免它。
Instant
会很好的。如果你真的需要
对于您现在无法更改或不想更改的遗留API,请按照问题中的方法进行转换。
编辑:现在默认
HOUR_OF_DAY
,不是
MILLI_OF_DAY
. 后者在只有毫秒丢失的情况下引发了冲突,但格式化程序似乎只对丢失时间的默认小时感到满意。