LocalDate - синтаксический анализ чувствителен к регистру

public class Solution {

    public static void main(String[] args) {
        System.out.println(isDateOdd("MAY 1 2013"));
    }

    public static boolean isDateOdd(String date) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy");
        formatter = formatter.withLocale(Locale.ENGLISH); 
        LocalDate outputDate = LocalDate.parse(date, formatter);
        return ((outputDate.getDayOfYear()%2!=0)?true:false);
    }
}

Я хочу знать, нечетное ли количество дней, прошедших с начала года до некоторой даты. Я пытаюсь использовать LocalDate для анализа даты из моей строки (MAY 1 2013), но получаю ошибку:

Исключение в основном потоке java.time.format.DateTimeParseException: текст «1 МАЯ 2013» не может быть проанализирован с индексом 0 в java.time.format.DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:1949) в java.time.format.DateTimeFormatter .parse (DateTimeFormatter.java:1851) в java.time.LocalDate.parse (LocalDate.java:400) в com.javarush.task.task08.task0827.Solution.isDateOdd (Solution.java:23) на com.javarush. task.task08.task0827.Solution.main (Solution.java:16)

Где проблема?


person Aldres    schedule 29.09.2017    source источник
comment
как насчет MAY 01 2013?   -  person Naman    schedule 29.09.2017
comment
Пробовал прямо сейчас, но все равно не работает.   -  person Aldres    schedule 29.09.2017
comment
МОЖЕТ быть также может быть @nullpointer   -  person achAmháin    schedule 29.09.2017


Ответы (3)


Если вы хотите использовать ввод месяца со всеми заглавными буквами, например ,MAY, вы должны использовать DateTimeFormatter без учета регистра:

public static boolean isDateOdd(String date) {
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern("MMM d yyyy")
            .toFormatter(Locale.ENGLISH);
    LocalDate outputDate = LocalDate.parse(date, formatter);
    return (outputDate.getDayOfYear() % 2 != 0);
}

Как указано в документации метода parseCaseSensitive() говорит:

Поскольку по умолчанию учитывается регистр, этот метод следует использовать только после предыдущего вызова #parseCaseInsensitive.

person Nikolas Charalambidis    schedule 29.09.2017
comment
Да! Проблема была в parseCaseInsensitive. Спасибо. Итак, без .parseCaseIntensitive он будет работать только с 1 мая 1998 года, не так ли? - person Aldres; 29.09.2017
comment
Нечувствительность к регистру означает, что корпус письма не влияет на обработку. Так что все варианты регистра месяца будут работать: mAy, MAY, may, mAY и т. Д. - person Nikolas Charalambidis; 29.09.2017
comment
@Aldres, вы правы, с учетом регистра по умолчанию будет распознан только May (заглавная M, маленький ay). - person Ole V.V.; 01.10.2017

Измените MAY на May и 1 на 01, и все заработает.

person achAmháin    schedule 29.09.2017

Часть дня должна состоять из двух цифр, то есть "MAY 01 2013".

Затем, если вы действительно хотите передавать названия месяцев в верхнем регистре, вы должны использовать конструктор вместе с parseCaseInsensitive().

Собираем все вместе:

public static boolean isDateOdd(String date) {

    DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
    builder.parseCaseInsensitive();
    builder.appendPattern("MMM dd yyyy");
    DateTimeFormatter formatter = builder.toFormatter(Locale.ENGLISH); 

    LocalDate outputDate = LocalDate.parse(date, formatter);
    return ((outputDate.getDayOfYear()%2!=0)?true:false);
 }
}
person Arnaud    schedule 29.09.2017