【问题标题】:Parsing date with timezone from a string从字符串中解析带有时区的日期
【发布时间】:2018-07-15 16:41:32
【问题描述】:

快速(我想)问题。如何将"2018-07-22 +3:00"这样的字符串解析为OffsetDateTime(将时间设置为0:0:0.0)?

DateTimeFormatter formatter =cDateTimeFormatter.ofPattern("yyyy-MM-dd xxx");
OffsetDateTime dt = OffsetDateTime.parse("2007-07-21 +00:00", formatter);

java.time.format.DateTimeParseException:文本'2007-07-21 +00:00' 无法解析:无法从中获取 OffsetDateTime TemporalAccessor: {OffsetSeconds=0},ISO 解析为 2007-07-21 类型 java.time.format.Parsed

【问题讨论】:

  • 嗯,我当然做到了。好的,会添加,但它不起作用
  • @Andreas 我添加了我所做的,它有什么帮助?
  • 您的问题文本显示 +3:00,这是一个无效的偏移量,因为小时只有 1 位数,但您的代码显示 +00:00 有 2 位数小时。您是否需要解析 1 位数小时?
  • @BbIKTOP HereHere。还有here

标签: java date java-time datetimeoffset


【解决方案1】:

这里的诀窍是首先获取TemporalAccessor

TemporalAccessor ta = DateTimeFormatter.ofPattern("yyyy-MM-dd XXX").parse("2018-07-22 +03:00");

从那里,您可以提取LocalDateZoneOffset

LocalDate date = LocalDate.from(ta);
ZoneOffset tz = ZoneOffset.from(ta);

然后像这样组合它们:

ZonedDateTime zdt = date.atStartOfDay(tz);

【讨论】:

  • 是的,会试试的,但看起来我需要的,谢谢。
【解决方案2】:

OffsetDateTime 需要时间,但您的格式字符串不提供该时间,因此您需要告诉 DateTimeFormatter 将默认时间设置为午夜。

另外,偏移量+3:00 无效,因为小时必须是 2 位数字,这意味着您需要先修复它。

这两个都可以:

public static OffsetDateTime parse(String text) {
    // Fix 1-digit offset hour
    String s = text.replaceFirst("( [+-])(\\d:\\d\\d)$", "$10$2");

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-MM-dd xxx")
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
            .toFormatter();
    return OffsetDateTime.parse(s, formatter);
}

测试

System.out.println(parse("2018-07-22 +3:00"));
System.out.println(parse("2018-07-22 +03:00"));
System.out.println(parse("2007-07-21 +00:00"));

输出

2018-07-22T00:00+03:00
2018-07-22T00:00+03:00
2007-07-21T00:00Z

【讨论】:

  • 是的,我知道 DateTimeFormatter 不接受单位数小时的偏移量,只是想知道为什么。实际上,在我的真实情况下可能会有更多变体,所以正则表达式不好用。不过没关系,这种情况我可以直接抛出异常,没问题。谢谢,它应该可以工作,但是获取 TemporalAccessor 然后提取日期、时间和时区更简单、更通用 - 可以检查是否提供了日期、时间和时区,并在必要时相应地设置默认值。
  • @BbIKTOP 使用正则表达式修复错误输入的好方法,但如果您需要支持其他偏移格式,则不一定那个特定的正则表达式模式. --- 为什么需要抛出异常?如果输入无效,parse 方法已经执行。
  • 我不知道输入字符串的确切格式,因此,我正在检查捕获异常的 DateTimeFormatters 集,而这种特殊情况就是问题所在。试过 DateTimeFormattersBuilder#append 但没有成功。我想至少支持整个预定义的格式化程序集,并且不想用正则表达式复制这些格式化程序。实际上,我从正则表达式开始,但后来切换到预定义的解析器和异常处理。所以,是的,它肯定会抛出一个异常,我会进一步抛出它。让这些客户也遭受 java 之苦! )))
  • 从 Java 9 开始,您可以使用 DateTimeFormatterBuilder 解析偏移量中的单个数字小时数。 docs.oracle.com/javase/9/docs/api/java/time/format/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-21
  • 2018-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多