在 DateTimeFormatter 中处理多种格式
Handling multiple formats in DateTimeFormatter
我正在使用 Java 8 开发一个函数,该函数必须处理以下日期从 String
到 LocalDateTime
的转换:
- 2019-06-20 12:18:07.207 +0000 UTC
- 2019-06-20 12:18:07.20 +0000 UTC
- 2019-06-20 12:18:07.2 +0000 UTC
- 2019-06-20 12:18:07 +0000 UTC
这些字符串是从我无法更改的外部库生成的。
按照 SO 回答 Optional parts in SimpleDateFormat 中给出的建议,我尝试使用类型 DateTimeFormatter
提供的可选格式,使用字符 [
和 ]
。我尝试了以下模式:
yyyy-MM-dd HH:mm:ss[.S[S[S]]] Z z
yyyy-MM-dd HH:mm:ss[.S[S][S]] Z z
然而,它们都不起作用。
有什么建议吗?
我认为为此目的使用 DateTimeFormatterBuilder
更好。对于可选部分,只需使用以下方法之一:
- OptionalStart() & OptionalEnd()
- 用 appendOptional()
附加整个可选模式
这是一个例子:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(""
+ "[yyyy-MM-dd HH:mm:ss.SSS Z z]"
+ "[yyyy-MM-dd HH:mm:ss.SS Z z]"
+ "[yyyy-MM-dd HH:mm:ss.S Z z]"
+ "[yyyy-MM-dd HH:mm:ss Z z]"
);
此外,您可以为每个可选的创建一个 dtf 并附加它们 appendOptional() 和 DateTimeFormatterBuilder
例如:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(HOUR_OF_DAY,2)
.optionalStart()
.appendValue(MINUTE_OF_HOUR,2)
.optionalEnd()
.optionalStart()
.appendValue(SECOND_OF_MINUTE,2)
.optionalEnd();
.toFormatter();
此代码未经测试,但每次都尝试在 start/end 个可选块中构建您的可选模式。
您可以使用 DateTimeFormatterBuilder
构建模式并重复使用 ISO_LOCAL_DATE
和 ISO_LOCAL_TIME
常量:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(" ")
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.appendPattern("[ Z z]")
.toFormatter();
ZonedDateTime dt = ZonedDateTime.parse(date, formatter);
诀窍在于 DateTimeFormatter.ISO_LOCAL_TIME
处理用于表示毫秒数的不同位数。来自 DateTimeFormatter.ISO_LOCAL_TIME
JavaDoc:
This returns an immutable formatter capable of formatting and parsing the ISO-8601 extended local time format. The format consists of:
[..]
One to nine digits for the nano-of-second. As many digits will be output as required.
我正在使用 Java 8 开发一个函数,该函数必须处理以下日期从 String
到 LocalDateTime
的转换:
- 2019-06-20 12:18:07.207 +0000 UTC
- 2019-06-20 12:18:07.20 +0000 UTC
- 2019-06-20 12:18:07.2 +0000 UTC
- 2019-06-20 12:18:07 +0000 UTC
这些字符串是从我无法更改的外部库生成的。
按照 SO 回答 Optional parts in SimpleDateFormat 中给出的建议,我尝试使用类型 DateTimeFormatter
提供的可选格式,使用字符 [
和 ]
。我尝试了以下模式:
yyyy-MM-dd HH:mm:ss[.S[S[S]]] Z z
yyyy-MM-dd HH:mm:ss[.S[S][S]] Z z
然而,它们都不起作用。
有什么建议吗?
我认为为此目的使用 DateTimeFormatterBuilder
更好。对于可选部分,只需使用以下方法之一:
- OptionalStart() & OptionalEnd()
- 用 appendOptional() 附加整个可选模式
这是一个例子:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(""
+ "[yyyy-MM-dd HH:mm:ss.SSS Z z]"
+ "[yyyy-MM-dd HH:mm:ss.SS Z z]"
+ "[yyyy-MM-dd HH:mm:ss.S Z z]"
+ "[yyyy-MM-dd HH:mm:ss Z z]"
);
此外,您可以为每个可选的创建一个 dtf 并附加它们 appendOptional() 和 DateTimeFormatterBuilder
例如:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(HOUR_OF_DAY,2)
.optionalStart()
.appendValue(MINUTE_OF_HOUR,2)
.optionalEnd()
.optionalStart()
.appendValue(SECOND_OF_MINUTE,2)
.optionalEnd();
.toFormatter();
此代码未经测试,但每次都尝试在 start/end 个可选块中构建您的可选模式。
您可以使用 DateTimeFormatterBuilder
构建模式并重复使用 ISO_LOCAL_DATE
和 ISO_LOCAL_TIME
常量:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(" ")
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.appendPattern("[ Z z]")
.toFormatter();
ZonedDateTime dt = ZonedDateTime.parse(date, formatter);
诀窍在于 DateTimeFormatter.ISO_LOCAL_TIME
处理用于表示毫秒数的不同位数。来自 DateTimeFormatter.ISO_LOCAL_TIME
JavaDoc:
This returns an immutable formatter capable of formatting and parsing the ISO-8601 extended local time format. The format consists of:
[..]
One to nine digits for the nano-of-second. As many digits will be output as required.