无法从字符串获取offsetdatetime

kcugc4gi  于 2021-07-23  发布在  Java
关注(0)|答案(2)|浏览(294)

我必须获得 OffsetDateTime 从字符串值
“2008-11-15t17:52:58”
我试过各种方法,但它给了这个错误。请查看下面的代码片段和错误,并提供注解。
第一种尝试方法:

ZonedDateTime.parse("2008-11-15T17:52:58", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")).toOffsetDateTime();

第二次尝试:

OffsetDateTime.parse("2014-06-09T17:15:04+02:00", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"));

我得到这个错误。

Text '2008-11-15T17: 52: 58' could not be parsed at index 19
1aaf6o9v

1aaf6o9v1#

你的模式 yyyy-MM-dd'T'HH:mm:ss.SSSZ 不包括要分析的区域偏移 +02:00 . 此格式类似于rfc-3339,它已经在datetimeformatter.iso\u date\u time中预先创建
如果你需要的话 OffsetDateTime 虽然您的输入没有偏移量,但您应该问问自己要使用什么偏移量。
datetimeformatter中有一个parsebest方法,它可以尝试多个时态查询,并将结果返回给您:

Stream.of("2008-11-15T17:52:58", "2014-06-09T17:15:04+02:00").map(s -> {
    return DateTimeFormatter.ISO_DATE_TIME.parseBest(s,
            OffsetDateTime::from, LocalDateTime::from);
}).forEach(ta -> {
    System.out.println("Type : " + ta.getClass());
    System.out.println("Value : " + ta.toString());
});

以下是输出:

Type : class java.time.LocalDateTime
Value : 2008-11-15T17:52:58
Type : class java.time.OffsetDateTime
Value : 2014-06-09T17:15:04+02:00

如您所见,您的第一个输入 2008-11-15T17:52:58 没有偏移量信息,因此无法将其解析为offsetdatetime。你可以很容易地发现并打电话给 .atOffset(...) 如果你知道用什么补偿
这里是修改后的版本来检测丢失的偏移量和转换 LocalDateTimeOffsetDateTime (如果您知道要使用什么偏移量)

Stream.of("2008-11-15T17:52:58", "2014-06-09T17:15:04+02:00").map(s -> {
    return DateTimeFormatter.ISO_DATE_TIME.parseBest(s,
            OffsetDateTime::from, LocalDateTime::from);
}).forEach(ta -> {

    final OffsetDateTime odt;

    if (ta instanceof OffsetDateTime) {
        odt = (OffsetDateTime) ta;
    } else {
        //here is 2-hour offset hardcoded. If you need OffsetDateTime
        //you should also know offset somehow
        odt = ((LocalDateTime) ta).atOffset(ZoneOffset.ofHours(2));
    }

    System.out.println("Type : " + odt.getClass());
    System.out.println("Value : " + odt.toString());
});

输出

Type : class java.time.OffsetDateTime
Value : 2008-11-15T17:52:58+02:00
Type : class java.time.OffsetDateTime
Value : 2014-06-09T17:15:04+02:00
ndh0cuux

ndh0cuux2#

如果你能像我一样 2014-06-09T17:15:04+02:00 ,然后它包含一个utc偏移量,在这里 +02:00 ,即2小时0分钟。在这种情况下,您可以:

OffsetDateTime parsedDateTime = OffsetDateTime.parse("2014-06-09T17:15:04+02:00");
    System.out.println(parsedDateTime);

2014-06-09t17:15:04+02:00
我们甚至不需要指定格式化程序。字符串采用iso 8601格式,并且 OffsetDateTime 而java.time的其他类则将最常见的iso8601变体解析为默认值。
如果你得到像 2008-11-15T17:52:58 ,偏移量丢失,因此无法直接转换为 OffsetDateTime 因为,顾名思义 OffsetDateTime 包括偏移量。如果你只知道一个人的名字,你就不能给他起名和姓。
如果您知道某个已知时区已被理解并打算使用,您可以转换为 OffsetDateTime 不过。如果你知道一个人的姓,也许你可以假设它也是这个人的姓?如果我们在代码中显式地进行转换,可能更容易理解。我们首先解析成 LocalDateTime . Local 在java.time的某些类名中,它的意思是“没有时区或偏移量”,因此这是适合您的字符串的类。格式仍然是ISO8601,所以我们仍然不需要格式化程序。

OffsetDateTime calculatedDateTime = LocalDateTime.parse("2008-11-15T17:52:58")
            .atZone(ZoneId.of("Asia/Karachi"))
            .toOffsetDateTime();
    System.out.println(calculatedDateTime);

2008-11-15t17:52:58+05:00
转换将指定时区中的任何夏季时间(dst)和其他时间变化考虑在内。

你的代码哪里出错了?

ZonedDateTime.parse("2008-11-15T17:52:58", DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")).toOffsetDateTime();

你的模式 yyyy-MM-dd'T'HH:mm:ss.SSSZ 例如,要求字符串包含秒小数的三位小数和不带冒号的utc偏移量 2008-11-15T17:52:58.000+0200 . 一种方法是使用格式化程序格式化和打印结果:

System.out.println(ZonedDateTime.now(ZoneId.of("Asia/Kolkata"))
            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")));

2021-02-13t02:59:04.324+0530
因为您试图解析的字符串既不包含秒的分数也不包含偏移量,所以解析失败。
你的第二次尝试也有同样的问题。你的弦里还是没有一秒的分数。这一次有一个偏移量,但冒号在小时和分钟之间,这是一个单一的 Z 不匹配。你可能用过 `` 这样的补偿。

链接

维基百科文章:iso 8601

相关问题