Дата разбора в UpperCase для LocalDate - PullRequest
0 голосов
/ 08 февраля 2019

Я пытаюсь разобрать строку FEBRUARY 2019 в LocalDate.

Это мой подход:

LocalDate month = LocalDate.parse("FEBRUARY 2019", DateTimeFormatter.ofPattern("MMMM yyyy"));

Или альтернативно установить Locale.US:

LocalDate month = LocalDate.parse("FEBRUARY 2019", DateTimeFormatter.ofPattern("MMMM yyyy", Locale.US));

Но все, что я получаю, это следующее исключение:

Exception in thread "main" java.time.format.DateTimeParseException: Text 'FEBRUARY 2019' could not be parsed at index 0

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Как сказал Джон Скит, у вас нет полной даты для анализа и вы можете использовать YearMonth.Альтернативой является указание дня по умолчанию.

Вместо того, чтобы предоставлять карту названий месяцев, вы также можете просто использовать библиотеку, такую ​​как WordUtils, чтобы преобразовать ввод в правильный формат, например, так:

final LocalDate month = LocalDate.parse(
        org.apache.commons.text.WordUtils.capitalizeFully("FEBRUARY 2019"),
        new DateTimeFormatterBuilder()
                    .appendPattern("MMMM uuuu")
                    .parseCaseInsensitive()
                    .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
                    .toFormatter(Locale.US));
0 голосов
/ 08 февраля 2019

Во-первых, я бы предположил, что у вас есть ввод не дата - это год и месяц.Так что разберите YearMonth, а затем создайте LocalDate из этого, как вы хотите.Я считаю, что проще всего сделать так, чтобы код обработки текста только имел дело с обработкой текста и выполнял любые другие преобразования отдельно, когда вы уже находитесь в области даты / времени.

Для обработки чувствительности к региструпроблема, вы можете создать DateTimeFormatter с разбором без учета регистра.Вот полный пример этого:

import java.time.*;
import java.time.format.*;
import java.util.*;

public class Test {
    public static void main(String[] args) {
        // Note: this would probably be a field somewhere so you don't need
        // to build it every time.
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern("MMMM yyyy")
            .toFormatter(Locale.US);

        YearMonth month = YearMonth.parse("FEBRUARY 2019", formatter);
        System.out.println(month);
    }
}

В качестве альтернативного подхода, который может быть полезен, если у вас другое представление, вы можете построить карту и передать ее в DateTimeFormatterBuilder.appendText.(Я обнаружил это только когда что-то напутало.)

import java.time.*;
import java.time.format.*;
import java.time.temporal.*;
import java.util.*;

public class Test {
    public static void main(String[] args) {
        // TODO: Build this map up programmatically instead?            
        Map<Long, String> monthNames = new HashMap<>();
        monthNames.put(1L, "JANUARY");
        monthNames.put(2L, "FEBRUARY");
        monthNames.put(3L, "MARCH");
        monthNames.put(4L, "APRIL");
        monthNames.put(5L, "MAY");
        monthNames.put(6L, "JUNE");
        monthNames.put(7L, "JULY");
        monthNames.put(8L, "AUGUST");
        monthNames.put(9L, "SEPTEMBER");
        monthNames.put(10L, "OCTOBER");
        monthNames.put(11L, "NOVEMBER");
        monthNames.put(12L, "DECEMBER");

        // Note: this would probably be a field somewhere so you don't need
        // to build it every time.
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendText(ChronoField.MONTH_OF_YEAR, monthNames)
            .appendLiteral(' ')
            .appendPattern("yyyy")
            .toFormatter(Locale.US);

        YearMonth month = YearMonth.parse("FEBRUARY 2019", formatter);
        System.out.println(month);
    }
}
...