Анализировать ISO-дату с меньшей специфичностью

Я пытаюсь разобрать строки, совместимые с ISO8601, которые указывают дату только до определенного момента, например 2018-02 для февраля 2018 года, пропуская день.

Пакет java.time, похоже, не может анализировать такие строки. Я пробовал следующее:

Instant.parse("2018-02");
LocalDateTime.parse("2018-02")
LocalDate.parse("2018-02", DateTimeFormatter.ISO_DATE);

которые терпят неудачу со следующей ошибкой

DateTimeParseException: текст '2018-02' не удалось проанализировать в индексе 7

Я также пробовал следующее, хотя на самом деле я не хочу указывать точный шаблон и просто принимаю все, что соответствует ISO8601:

LocalDate.parse("2018-02", DateTimeFormatter.ofPattern("yyyy-MM"));

что не работает с:

java.time.format.DateTimeParseException: текст '2018-02' не может быть проанализирован: невозможно получить LocalDate от TemporalAccessor: {MonthOfYear = 2, Year = 2018}, ISO типа java.time.format.Parsed

Есть ли способ проанализировать такие строки ISO8601 с помощью пакета java.time?


person Felk    schedule 15.02.2018    source источник
comment
Ну, дата - это день, а не месяц ... - Вы можете просто предположить один день, например первое и добавьте его к полученной строке даты.   -  person Thomas    schedule 15.02.2018
comment
Ваши строки всегда такие, или это требование к синтаксическому анализу 2018-02, 2018-02-15, 2018-02-15T12 и т. Д.?   -  person Ole V.V.    schedule 15.02.2018
comment
Технически мне нужно только проанализировать yyyy-MM, но я бы хотел, чтобы я мог сделать его надежным, приняв любую дату ISO8601, включая yyyy-MM-dd и временные части.   -  person Felk    schedule 15.02.2018


Ответы (1)


Да, вы можете использовать класс YearMonth :

YearMonth ym = YearMonth.parse("2018-02");

(входные данные находятся в формате ISO, поэтому здесь нет необходимости предоставлять средство форматирования).


ОБНОВЛЕНИЕ

В комментарии вы указываете, что ввод может быть 2018-02 или 2018-02-01, и в этом случае вы хотите игнорировать день. В этом случае вы можете использовать:

//note the optional day
DateTimeFormatter FMT = DateTimeFormatter.ofPattern("yyyy-MM[-dd]");

YearMonth ym = YearMonth.from(FMT.parseBest(input, YearMonth::from, LocalDate::from));
person assylias    schedule 15.02.2018
comment
У меня работает, но есть ли способ получить экземпляр YearMonth путем анализа произвольных локальных дат ISO8601? Это не подходит для 2018-02-01 или большей точности, что является возможным вводом, если кто-то решает выводить даты с точностью до месяца как даты ISO8601 с полной точностью. - person Felk; 15.02.2018
comment
Предлагаю уточнить свой вопрос - какой выход вы хотите в таком случае? LocalDate? Вы также хотите LocalDate, когда ввод 2018-02? В таком случае, какой день использовать? - person assylias; 15.02.2018
comment
Я хочу YearMonth. Следует отбросить ненужную точность - person Felk; 15.02.2018