从字符串中解析带时区的日期

Parsing date with timezone from a string

快速(我想)问题。如何将 "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: Text '2007-07-21 +00:00' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {OffsetSeconds=0},ISO resolved to 2007-07-21 of type java.time.format.Parsed

这里的技巧是从获取 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);

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

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

这两个都可以:

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

    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