java - 根据解析的 TemporalAccessor 有条件地创建 LocalDateTime、ZonedDateTime 或 OffsetDateTime
问题描述
给定一个DateTimeFormatter
定义为:
public static final DateTimeFormatter DATE_TIME = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append( ISO_LOCAL_DATE )
.optionalStart().appendLiteral( ' ' ).optionalEnd()
.optionalStart().appendLiteral( 'T' ).optionalEnd()
.append( ISO_LOCAL_TIME )
.optionalStart().appendLiteral( ' ' ).optionalEnd()
.optionalStart().appendZoneOrOffsetId().optionalEnd()
.toFormatter();
我想有条件地创建一个LocalDateTime
,ZonedDateTime
或OffsetDateTime
基于解析是否包含区域ID、偏移量或两者都不包含。
到目前为止,我有:
DATE_TIME.parse(
text,
(temporal) -> {
// see if there is an offset
final ZoneOffset offset = temporal.query( TemporalQueries.offset() );
if ( offset != null ) {
return OffsetDateTime.from( temporal );
}
// see if there is a tz
final ZoneId zoneId = temporal.query( TemporalQueries.zoneId() );
if ( zoneId != null ) {
return ZonedDateTime.from( temporal );
}
// otherwise its a LocalDateTime
return LocalDateTime.from( temporal );
}
);
但我发现,区域偏移量永远不会被“识别”——即使文本包含偏移量,它也总是被报告为区域 ID。例如,鉴于"1999-12-31 12:59:59 +02:00"
我期望一个OffsetDateTime
. 但是,"+02:00"
始终将其解析为区域 ID。最终,考虑到分区和偏移之间的互惠,它可以工作。但作为(可能超出顶部)正确性的问题,我想将这些视为OffsetDateTime
.
我是否缺少能够做出这种区分的东西?
谢谢!
解决方案
看起来这实际上是 Java 8 中的一个错误。如果将 的值存储DateTimeFormatter#parse
在Temporal
变量中并打印其getClass()
,则在使用 Java 8 编译和运行时会收到以下信息:
class java.time.ZonedDateTime
但是,当使用 Java 11 编译和运行时,输出是您所期望的:
class java.time.OffsetDateTime
如果我设法找到它,我将四处搜索特定的错误报告并编辑此答案。这样,我们就可以确定错误的原因以及修复它的 Java 版本。
推荐阅读
- php - PHP:从变量的文本区域创建数组的最佳方法
- java - 如何使 feign disable-ssl-validation 属性在 Spring Boot 上工作
- php - 更改端口后 Wamp 服务器无法访问互联网
- capybara - Capybara - 我必须点击capybara按钮,他找不到
- laravel - Laravel 调用未定义的方法。方法存在
- powershell - 有没有办法使用powershell以模式重命名文件夹中的文件?
- python - 有向图可以有两个 DFS 遍历吗?
- node.js - 如何更改 File Watcher 的 WebStorm 环境设置?
- c# - 如何绑定对象
- azure - 如何设置自动 nuget 版本增量