Java - 解析带有可选秒数的日期
Java - Parse date with optional seconds
给定这个日期我想解析:12 月 15 日 16:00 +01:00
使用此代码
Map<Long, String> ordinalNumbers = new HashMap<>(42);
ordinalNumbers.put(1L, "1st");
ordinalNumbers.put(2L, "2nd");
ordinalNumbers.put(3L, "3rd");
ordinalNumbers.put(21L, "21st");
ordinalNumbers.put(22L, "22nd");
ordinalNumbers.put(23L, "23rd");
ordinalNumbers.put(31L, "31st");
for (long d = 1; d <= 31; d++) {
ordinalNumbers.putIfAbsent(d, "" + d + "th");
}
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendText(ChronoField.DAY_OF_MONTH, ordinalNumbers)
.appendPattern(" MMM HH:mm[:ss] xxx")
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter().withLocale(Locale.ENGLISH);
ZonedDateTime eventDate = ZonedDateTime.parse("15th Dec 16:00 +01:00", formatter);
但我总是得到
java.time.DateTimeException: Unable to obtain ZonedDateTime from TemporalAccessor: {DayOfMonth=15, MonthOfYear=12, OffsetSeconds=3600},ISO resolved to 16:00 of type java.time.format.Parsed
您可以在此处在线试用:https://repl.it/repls/NaiveRegularEquation
请告诉我我做错了什么。
更新:
缺少年份是问题所在。
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendText(ChronoField.DAY_OF_MONTH, ordinalNumbers)
.appendPattern(" MMM HH:mm[:ss] xxx")
.parseDefaulting(ChronoField.YEAR, 2018)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter().withLocale(Locale.ENGLISH);
指定年份
ZonedDateTime
需要一个年份字段,而您没有提供。
您可以设置默认值:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseDefaulting(ChronoField.YEAR_OF_ERA, ZonedDateTime.now().getYear()) // set default year
.appendText(ChronoField.DAY_OF_MONTH, ordinalNumbers)
.appendPattern(" MMM HH:mm[:ss] xxx")
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter().withLocale(Locale.ENGLISH);
给定这个日期我想解析:12 月 15 日 16:00 +01:00
使用此代码
Map<Long, String> ordinalNumbers = new HashMap<>(42);
ordinalNumbers.put(1L, "1st");
ordinalNumbers.put(2L, "2nd");
ordinalNumbers.put(3L, "3rd");
ordinalNumbers.put(21L, "21st");
ordinalNumbers.put(22L, "22nd");
ordinalNumbers.put(23L, "23rd");
ordinalNumbers.put(31L, "31st");
for (long d = 1; d <= 31; d++) {
ordinalNumbers.putIfAbsent(d, "" + d + "th");
}
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendText(ChronoField.DAY_OF_MONTH, ordinalNumbers)
.appendPattern(" MMM HH:mm[:ss] xxx")
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter().withLocale(Locale.ENGLISH);
ZonedDateTime eventDate = ZonedDateTime.parse("15th Dec 16:00 +01:00", formatter);
但我总是得到
java.time.DateTimeException: Unable to obtain ZonedDateTime from TemporalAccessor: {DayOfMonth=15, MonthOfYear=12, OffsetSeconds=3600},ISO resolved to 16:00 of type java.time.format.Parsed
您可以在此处在线试用:https://repl.it/repls/NaiveRegularEquation 请告诉我我做错了什么。
更新: 缺少年份是问题所在。
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendText(ChronoField.DAY_OF_MONTH, ordinalNumbers)
.appendPattern(" MMM HH:mm[:ss] xxx")
.parseDefaulting(ChronoField.YEAR, 2018)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter().withLocale(Locale.ENGLISH);
指定年份
ZonedDateTime
需要一个年份字段,而您没有提供。
您可以设置默认值:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseDefaulting(ChronoField.YEAR_OF_ERA, ZonedDateTime.now().getYear()) // set default year
.appendText(ChronoField.DAY_OF_MONTH, ordinalNumbers)
.appendPattern(" MMM HH:mm[:ss] xxx")
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter().withLocale(Locale.ENGLISH);