将非 ISO 8601 解析为 ISO_INSTANT
Parse non ISO 8601 to ISO_INSTANT
我正在尝试将此字符串 2020-05-20 14:27:00.943000000 +00:00
和此 Wed May 20 14:27:00 CEST 2020
解析为 ISO_INSTANT,但总是 return 此异常
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; }
如何转换这种类型?
异常的原因是字符串 2020-05-20 14:27:00.943000000 +00:00
和 ISO_INSTANT
之间的格式不同; from DateTimeFormatter ISO_INSTANT
接受像 2011-12-03T10:15:30Z
这样的字符串,这不是你的情况。此问题的可能解决方案是使用自定义 DateTimeFormatter
,如下所示:
String fechaHora = "2020-05-20 14:27:00.943000000 +00:00";
DateTimeFormatter formatter =DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS ZZZZZ");
TemporalAccessor temporalAccessor = formatter.parse(fechaHora);
LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
Instant result = Instant.from(zonedDateTime);
System.out.println(result); //<-- it will print 2020-05-20T12:27:00.943Z
tl;博士
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 格式。将日期和时间之间的 SPACE 替换为 T
。删除时间和偏移量之间的SPACE。
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
class。这已在 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
如果您需要 return 一个 Instant
,请致电 toInstant
。
Instant instant = odt.toInstant() ;
要在时区上下文中查看同一时刻,请应用 ZoneId
以获得 ZonedDateTime
对象。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
OffsetDateTime
和 ZonedDateTime
对象代表同一时刻,时间轴上的同一点。
我正在尝试将此字符串 2020-05-20 14:27:00.943000000 +00:00
和此 Wed May 20 14:27:00 CEST 2020
解析为 ISO_INSTANT,但总是 return 此异常
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; }
如何转换这种类型?
异常的原因是字符串 2020-05-20 14:27:00.943000000 +00:00
和 ISO_INSTANT
之间的格式不同; from DateTimeFormatter ISO_INSTANT
接受像 2011-12-03T10:15:30Z
这样的字符串,这不是你的情况。此问题的可能解决方案是使用自定义 DateTimeFormatter
,如下所示:
String fechaHora = "2020-05-20 14:27:00.943000000 +00:00";
DateTimeFormatter formatter =DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS ZZZZZ");
TemporalAccessor temporalAccessor = formatter.parse(fechaHora);
LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
Instant result = Instant.from(zonedDateTime);
System.out.println(result); //<-- it will print 2020-05-20T12:27:00.943Z
tl;博士
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 格式。将日期和时间之间的 SPACE 替换为 T
。删除时间和偏移量之间的SPACE。
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
class。这已在 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
如果您需要 return 一个 Instant
,请致电 toInstant
。
Instant instant = odt.toInstant() ;
要在时区上下文中查看同一时刻,请应用 ZoneId
以获得 ZonedDateTime
对象。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
OffsetDateTime
和 ZonedDateTime
对象代表同一时刻,时间轴上的同一点。