java - 将非 ISO 8601 解析为 ISO_INSTANT

标签 java date parsing time instant

我正在尝试解析此字符串 2020-05-20 14:27:00.943000000 +00:00 和此 Wed May 20 14:27:00 CEST 2020到 ISO_INSTANT,但始终返回此异常

java.time.format.DateTimeParseException: Text '2020-05-20 14:27:00.943000000 +00:00' could not be parsed at index 10

我的代码是:

protected Instant parseDateTime(String fechaHora) {

        DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
        TemporalAccessor temporalAccessor = formatter.parse(fechaHora);
        LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);
        ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
        Instant result = Instant.from(zonedDateTime);
        return result; }

如何转换这种类型?

最佳答案

tl;dr

OffsetDateTime.parse( 
    "2020-05-20 14:27:00.943000000 +00:00" , 
    DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss.SSSSSSSSS xxx" )
)
.toInstant()

修复代码

您的代码在几个方面存在缺陷。

TemporalAccessor 的使用在这里是不必要和不合适的。引用its Javadoc :

This interface is a framework-level interface that should not be widely used in application code. Instead, applications should create and pass around instances of concrete types

LocalDateTime 在这里不合适,因为它去除了重要信息、时区或与 UTC 的偏移量。

您指定的格式化程序的格式化模式与您的输入不匹配。

解决方案

处理您的输入字符串以符合标准 ISO 8601格式。用 T 替换日期和时间之间的空格。删除时间和偏移量之间的空格。

String input = "2020-05-20 14:27:00.943000000 +00:00" ;
String[] strings = input.split( " " ) ;
String modifiedInput = strings[0] + "T" + strings[1] + strings[2] ;

解析为 OffsetDateTime,这是一个在与 UTC 的偏移量上下文中带有时间的日期。

OffsetDateTime odt = OffsetDateTime.parse( modifiedInput ) ;

或者,定义格式模式以匹配您的输入字符串。使用 DateTimeFormatter 类。这已在 Stack Overflow 上多次介绍,因此请搜索以了解更多信息。

您尝试使用的预定义格式化程序 DateTimeFormatter.ISO_INSTANT 与您的输入不匹配。您的输入不符合该格式化程序使用的 ISO 8601 标准。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss.SSSSSSSSS xxx" ) ;
String input = "2020-05-20 14:27:00.943000000 +00:00" ;
OffsetDateTime odt = OffsetDateTime.parse( input , f ) ;

查看此 code run live at IdeOne.com .

odt.toString(): 2020-05-20T14:27:00.943Z

如果你需要返回一个Instant,调用toInstant

Instant instant = odt.toInstant() ;

要在时区上下文中查看同一时刻,请应用 ZoneId 以获取 ZonedDateTime 对象。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

OffsetDateTimeZonedDateTime 对象代表同一时刻,时间轴上的同一点。

关于java - 将非 ISO 8601 解析为 ISO_INSTANT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61936487/

相关文章:

java - Xamarin 升级导致 "class file has wrong version 52.0, should be 50.0"错误

Java null 检查为什么使用 == 而不是 .equals()

.net - 如何分割 RTF 文件

sql - 解析 SQL 语句的库

c# - 泰国/佛教时代时间的 DateTime.ParseExact 问题

java - 使用数组列表并创建对象

java - Spring 获取 ServletContext 并将其作为 Bean 提供

javascript - 使用 JavaScript 创建日期和分钟数组

java - 使用 DateTimeFormatter.ofLocalizedDate 格式化 MonthDay

PHP 将 DATETIME 转换为时间前函数,秒,分钟,小时,天等