0

Given this date I want to parse: 15th Dec 16:00 +01:00

with this code

    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);

but I always get

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

You can try it out online here: https://repl.it/repls/NaiveRegularEquation Please tell me what I do wrong.

UPDATE: The missing year was the problem.

 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);
xingbin
  • 27,410
  • 9
  • 53
  • 103
apreg
  • 637
  • 8
  • 18
  • 1
    I guess the problem is that there is no year part in the date string. It looks like I'm too tired. – apreg Dec 16 '18 at 03:52

1 Answers1

3

Specify year

ZonedDateTime needs a year field, while you did not provide it.

You can set a default value:

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);
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
xingbin
  • 27,410
  • 9
  • 53
  • 103