当前位置: 首页 > 知识库问答 >
问题:

如何将“2021 11月20日01:00”格式的日期字符串解析为ZonedDateTime-错误

袁泰平
2023-03-14

如何将“2021 11月20日01:00”格式的日期解析为分区日期时间?我试着这样做:

String value = "2021-11-20+01:00";
ZonedDateTime zDate = ZonedDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-ddxxx"));

但是得到了这个奇怪的错误:

Java语言时间总体安排DateTimeParseException:无法解析文本“2021 11月20日01:00”:无法从TemporalAccessor获取ZonedDateTime:{OffsetSeconds=3600},ISO解析为java类型的2021 11月20日。时间总体安排已解析

...不支持的字段:Instant秒...

有什么建议吗?欧洲VIES增值税ID检查系统在接收XML(SOAP)响应时使用此时间格式:<代码>

有趣的是Javadoc说“三个字母(x)输出小时和分钟,带有冒号,例如‘01:30’”。那么为什么上面的模式不起作用呢?

也尝试了这个-同样的错误:

ZonedDateTime zDate = ZonedDateTime.parse(value, DateTimeFormatter.ISO_OFFSET_DATE);

完整的错误日志:

Exception in thread "main" java.time.format.DateTimeParseException: Text '2021-11-20 +01:00' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {OffsetSeconds=3600},ISO resolved to 2021-11-20 of type java.time.format.Parsed
    at java.base/java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:2017)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1952)
    at java.base/java.time.OffsetDateTime.parse(OffsetDateTime.java:402)
    at javaapplication5.JavaApplication5.checkVATatVIES(JavaApplication5.java:162)
    at javaapplication5.JavaApplication5.main(JavaApplication5.java:65)
Caused by: java.time.DateTimeException: Unable to obtain OffsetDateTime from TemporalAccessor: {OffsetSeconds=3600},ISO resolved to 2021-11-20 of type java.time.format.Parsed
    at java.base/java.time.OffsetDateTime.from(OffsetDateTime.java:370)
    at java.base/java.time.format.Parsed.query(Parsed.java:235)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
    ... 3 more
Caused by: java.time.DateTimeException: Unable to obtain Instant from TemporalAccessor: {OffsetSeconds=3600},ISO resolved to 2021-11-20 of type java.time.format.Parsed
    at java.base/java.time.Instant.from(Instant.java:378)
    at java.base/java.time.OffsetDateTime.from(OffsetDateTime.java:365)
    ... 5 more
Caused by: java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: InstantSeconds
    at java.base/java.time.format.Parsed.getLong(Parsed.java:203)
    at java.base/java.time.Instant.from(Instant.java:373)
    ... 6 more

使用OpenJDK 11。

共有3个答案

燕文昌
2023-03-14

您可以自己将ur模式指定为如下字符串:

String str = "2021-11-20+01:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd+HH:mm");
LocalDateTime date= LocalDateTime.parse(str, formatter);
伯英锐
2023-03-14
org.threeten.extra.OffsetDate.parse( "2021-11-20+01:00" )

java。Java中内置的时间类不提供日期与偏移量相结合的类。所以你的解析尝试毫无意义。

ThreeTen-Extra项目旨在补充java.time.的功能,它包括满足您特定需求的OffsetDate类。将库添加到您的项目中。

String input = "2021-11-20+01:00" ;
OffsetDate od = OffsetDate.parse( input ) ;

从该对象可以获得局部日期部分或区域偏移部分。您可以确定其他日期时间值,例如添加一天中的某个时间以获得偏移日期时间。

您评论:

如果我在21日凌晨00:30提出请求,我会收到包含20日的回复。。因为我们的时间是UTC 2,他们的时间是UTC 1

顺便提一句,我建议养成一个习惯,使用完整形式的小时偏移量,填充零,也填充分钟。虽然有各种标准允许,但我见过多个库在缩写时失败。因此,我建议使用“02:00”而不是“UTC 2”。

下面是一些示例代码,演示了您所描述的场景。我们使用非洲/布拉柴维尔的时区,因为当时的偏移量为01:00,我们使用欧洲/加里宁格勒的偏移量为02:00。

LocalDate ld = LocalDate.of( 2021 , Month.NOVEMBER , 21 );
LocalTime lt = LocalTime.of( 0 , 30 );
ZoneId zKaliningrad = ZoneId.of( "Europe/Kaliningrad" );
ZonedDateTime zdtKaliningrad = ZonedDateTime.of( ld , lt , zKaliningrad );

ZoneId zBrazzaville = ZoneId.of( "Africa/Brazzaville" );
ZonedDateTime zdtBrazzaville = zdtKaliningrad.withZoneSameInstant( zBrazzaville );

OffsetDate od = OffsetDate.from( zdtBrazzaville );

OffsetDateTime odt = od.atTime( LocalTime.MIN );
ZonedDateTime asSeenInKaliningrad = odt.atZoneSameInstant( zKaliningrad );

运行时。

zdtKaliningrad = 2021-11-21T00:30+02:00[Europe/Kaliningrad]
zdtBrazzaville = 2021-11-20T23:30+01:00[Africa/Brazzaville]
od = 2021-11-20+01:00
odt = 2021-11-20T00:00+01:00
asSeenInKaliningrad = 2021-11-20T01:00+02:00[Europe/Kaliningrad]

就我个人而言,我质疑带偏移的日期概念的实用价值,但这与你的问题无关。

在特定时区工作通常比仅仅使用偏移量工作问题更少。

我认为,将区域作为一个时刻来跟踪日期更有意义,即一天开始时时间线上的点,以及指定的时区,而不是偏移量。

String result = 
    LocalDate
        .of( 2021 , 11 , 20 )
        .atStartOfDay( ZoneId.of( "Africa/Brazzaville" ) )
        .toString() 
;

看到这个代码运行在IdeOne.com.

2021-11-20T00:00 01:00[非洲/布拉柴维尔]

对于表示一天的文本的数据交换,我建议以扩展ISO 8601的格式传输此字符串(2021-11-20T00:00 01:00[Africa/Brazzaville]),将时区名称附加在方括号中。

蒋星驰
2023-03-14

没有只包含日期和时区的Java类型。正如它们的名称所暗示的那样,ZonedDateTime和OffsetDateTime包含日期和时间。因此,您需要创建一个假定一天中默认时间的格式化程序:

String value = "2021-11-20+01:00";

DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
builder.appendPattern("yyyy-MM-ddxxx");
builder.parseDefaulting(ChronoField.HOUR_OF_DAY, 0);
DateTimeFormatter formatter = builder.toFormatter();

ZonedDateTime zDate = ZonedDateTime.parse(value, formatter);

当然,一天中的小时可以是您选择的任何值:例如,表示中午的12。但它必须是有效的。

 类似资料:
  • 我尝试使用低于模式的模式时出现低于错误 有人能解释一下这背后的原因吗?? 以上模式收到错误:java。时间总体安排DateTimeParseException:无法在索引19处分析文本“2021-08-03T10:00:00EDT”

  • 我有类似“2021-06-01”的字符串,我希望将其转换为“2021-06-01T00:00:00+02:00”。我知道,最简单的解决方案是串接: 但是,我希望使用来实现。目前我的解决方案是: 然后使用: 然而,它抱怨说: 有解决办法吗?

  • 问题内容: 我正在尝试将字符串转换为日期 但在我看来,它有一个。的。这是为什么?我想生成一个日期 问题答案: 日期字符串- 符合- d-每月的某天 M-一年中的月份 y-年 …

  • 问题内容: 我正在管理一个来自Alfresco Properties的日期,并且该日期处于指定的日期(2010年7月13日星期二00:00:00 CEST),我需要将其转换为Java日期…我四处查看并发现了数百万个日期各种字符串到日期转换形式的帖子,还有此页面,因此我尝试了以下操作: 但是它引发了一个异常。(该异常是(SSollevata un’eccezione durante la gesti

  • 我有以下两个日期: 2009年10月8日 我正在使用Jackson将日期从rest api转换为joda Datetime。 我以为模式“dd MMM.yyyy”可以工作,但“may”没有点,所以在那一点上崩溃了。 有没有解决方案,或者我必须自己编写datetime解析器? jackson中的注释是: 所以只允许有一种约会模式。

  • 问题内容: 如何将下面的日期字符串解析为一个Date对象? 引发异常… 问题答案: 模式是错误的。您有3个字母的天的缩写,因此必须为。您有3个字母的月份缩写,因此必须为。由于这些日和月的缩写对语言环境敏感,因此您也希望将语言环境明确指定为英语,否则它将使用平台默认语言环境,而语言环境本身可能不是英语。 这在这里打印 根据我的时区是正确的。 如果您不想使用代替,我也会重新考虑。阅读javadoc以获