Установите дату ввода и добавьте ее в список

В принципе, я хочу установить даты и сохранить их в списке. Из моего кода ниже:

public List<RecordList> createRecord(BigDecimal yr){

    for (int index = 0; index <= 14; index++) {
        RecordList value = new RecordList();
        if(index == 0){
            value.setStartDt(toDate(("01-04-" + yr)));
            value.setEndDt(toDate(("30-04-" + yr)));
        }
        if(index == 1){
            value.setStartDt(toDate(("01-05-" + yr.add(new BigDecimal(1)))));
            value.setEndDt(toDate(("31-05-" + yr.add(new BigDecimal(1)))));
        }
        createRecord.add(newRecordValue);
    return createRecord;
}

private Date toDate(String date) {
    Date newDate = null;
    try {
        newDate = new SimpleDateFormat("dd-MM-YYYY").parse(date);
    }
    catch (ParseException e) {
        e.printStackTrace();
    }
    return newDate;
}

что происходит, когда я устанавливаю год на 2017, вывод не соответствует тому, что я установил:

"StartDate": "30-12-2017",
 "EndDate": "30-12-2017"

и он не увеличивается до следующего года, вместо этого он уменьшается до:

"StartDate": "30-12-2016",
 "EndDate": "30-12-2016"

person newbie    schedule 08.06.2017    source источник
comment
О, это было бы намного проще и естественнее сделать с LocalDate из JSR-310 (встроено в Java 8, а также перенесено в Java 6 и 7). В наши дни вы не должны использовать SimpleDateFormat и, в частности, не для такой задачи, как эта.   -  person Ole V.V.    schedule 08.06.2017


Ответы (2)


верхний регистр Y - год недели. Вы должны использовать нижний регистр y для календарного года:

newDate = new SimpleDateFormat("dd-MM-yyyy").parse(date);

Для получения дополнительной информации прочитайте Javadoc SimpleDateFormat.

person Jens    schedule 08.06.2017

Ответ @Jens правильный и должен быть принят.

Я добавляю несколько предложений как улучшить обработку ошибок. Как видите, SimpleDateFormat ничего не говорит о том, что не так с вашим кодом. И я уверен, что такое поведение уже заставило многих людей выпускать тонны кода для синтаксического анализа с иногда «удивительным» поведением. К счастью, вы случайно обнаружили, что что-то не так.


Ява-8

Новая встроенная библиотека java.time (доступная начиная с Java-8) не будет анализировать, а выдаст исключение

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-YYYY");
LocalDate d = LocalDate.parse("30-12-2017", dtf);

со следующим сообщением об ошибке:

Исключение в потоке «основной» java.time.format.DateTimeParseException: текст «30-12-2017» не может быть проанализирован: невозможно получить LocalDate из TemporalAccessor: {MonthOfYear = 12, WeekBasedYear [WeekFields [MONDAY, 4]] = 2017 , ДеньМесяца=30}...

Существование поля «WeekBasedYear» в сообщении об ошибке должно пролить свет на то, что не так, поэтому вы обратитесь к документации, чтобы найти правильный символ шаблона.

Кстати, для Java-6+7 также доступен бэкпорт Threeten-BP. И я сейчас также протестировал популярную библиотеку Joda-Time:

DateTimeFormatter dtf = DateTimeFormat.forPattern("dd-MM-YYYY");
System.out.println(dtf.parseLocalDate("30-12-2017")); // 2017-12-30 (don't use it!)

Таким образом, Java-8 также является улучшением для Joda-Time, которое не видит никаких проблем в вашем шаблоне.


Моя библиотека Time4J

ChronoFormatter<PlainDate> cf =
    ChronoFormatter.ofDatePattern("dd-MM-YYYY", PatternType.CLDR, Locale.ROOT);
LocalDate d = cf.parse("30-12-2017").toTemporalAccessor(); // not even executed

Здесь конструкция парсера завершается с ошибкой со следующим сообщением:

java.lang.IllegalArgumentException:
Y, поскольку год на основе недели требует формата недели и даты: дд-ММ-ГГГГ

person Meno Hochschild    schedule 08.06.2017