Проблема с разбором даты на арабском языке - PullRequest
5 голосов
/ 06 марта 2019

У меня есть функция конвертера даты, например:

public static LocalDate getLocalDateFromString(String dateString) {
    DecimalStyle defaultDecimalStyle = DateTimeFormatter.ISO_LOCAL_DATE.getDecimalStyle();
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE.withDecimalStyle(defaultDecimalStyle.withZeroDigit('\u0660'));
    LocalDate date = LocalDate.parse(dateString, dateTimeFormatter);
    return date;
}

Она отлично работает для арабских дат, таких как ٢٠١٩-٠٤-١٥, но когда я передаю обычную дату, например 2019-07-31, возникает исключение, потому что форматтердругого типа:

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

У меня нет контроля над датой передачи, так как она передается пользователем.

Как использовать одну и ту же функцию для анализа обоихдаты?

Ответы [ 3 ]

4 голосов
/ 06 марта 2019

Знай свою строку

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

Возьми на вкус и действуй соответственно

Если нет, конечно, есть выход. Нижеследующее является низкоуровневым, но должно быть общим.

public static LocalDate getLocalDateFromString(String dateString) {
    DateTimeFormatter dateFormatter = DateTimeFormatter.ISO_LOCAL_DATE;
    // Take a digit from dateString to determine which digits are used
    char sampleDigit = dateString.charAt(0);
    if (Character.isDigit(sampleDigit)) {
        // Subtract the numeric value of the digit to find the zero digit in the same digit block
        char zeroDigit = (char) (sampleDigit - Character.getNumericValue(sampleDigit));
        assert Character.isDigit(zeroDigit) : zeroDigit;
        assert Character.getNumericValue(zeroDigit) == 0 : zeroDigit;
        DecimalStyle defaultDecimalStyle = dateFormatter.getDecimalStyle();
        dateFormatter = dateFormatter
                .withDecimalStyle(defaultDecimalStyle.withZeroDigit(zeroDigit));
    }
    // If the examined char wasn’t a digit, the following parsing will fail;
    // but in that case the best we can give the caller is the exception from that failed parsing.
    LocalDate date = LocalDate.parse(dateString, dateFormatter);
    return date;
}

Давайте попробуем:

    System.out.println("Parsing Arabic date string to  "
            + getLocalDateFromString("٢٠١٩-٠٤-١٥"));
    System.out.println("Parsing Western date string to "
            + getLocalDateFromString("2019-07-31"));

Вывод этого фрагмента:

Parsing Arabic date string to  2019-04-15
Parsing Western date string to 2019-07-31
0 голосов
/ 06 марта 2019

Два средства форматирования

Если вы ожидаете один из двух форматов во входящих строках, установите два объекта DateTimeFormatter, по одному для каждого ожидаемого формата.

Попробуйте оба

Попробуйте один форматтер, перехватывая DateTimeParseException.Если бросили, попробуйте другой.Если второй бросок также, то вы знаете, что получили неожиданный ошибочный ввод.

Если у вас более двух ожидаемых форматов, соберите все возможные DateTimeFormatter объекты.Цикл коллекции, попробуйте каждый для анализа входных данных, пока один не бросит исключение синтаксического анализа.

0 голосов
/ 06 марта 2019

Я думаю, что лучшее решение - переопределить метод в вашем классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...