Java DateFormat и SimpleDateFormat возвращают неправильную дату

Сегодня вторник, 9 февраля 2010 г., и когда я печатаю дату, я получаю неправильную дату:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

Date today = formatter.parse(String.format("%04d-%02d-%02d",
        Calendar.getInstance().get(Calendar.YEAR),
        Calendar.getInstance().get(Calendar.MONTH),
        Calendar.getInstance().get(Calendar.DAY_OF_MONTH)));

System.out.println("Today is " + today.toString());

Результат строки печати: «Сегодня суббота, 09 января, 00:00:00 CST 2010».

Это определенно не суббота, 09 января, это вторник, 09 февраля. Я предполагаю, что делаю что-то не так, так что может ли кто-нибудь сообщить мне, что здесь не так? Нужно ли вручную устанавливать день недели?

Обновление Примечание: сегодня я не хочу инициализировать new Date(), потому что хочу, чтобы часы, минуты, секунды и миллисекунды были инициализированы 0. Это необходимо, чтобы я мог сравнить введенную пользователем дату с сегодняшним днем: если пользователь вводит сегодняшнюю дату, а я использую модуль форматирования для создания объекта Date, то если я инициализирую сегодня с помощью new Date() и сравниваю две даты, сегодня будет после даты, выбранной пользователем (что неверно). Таким образом, мне нужно инициализировать сегодня в начале дня без часов/мин/сек/мс.


person Kiril    schedule 10.02.2010    source источник
comment
Почему, черт возьми, вы получили бы сегодня таким образом? Почему не Дата сегодня = новая Дата ()? Ваш путь долгий и, как видите, даже не правильный.   -  person duffymo    schedule 10.02.2010
comment
@duffymo Это в JSP. Предположим, что пользователь выбирает сегодняшний день в качестве желаемого дня, а затем его ввод перенаправляется на другой JSP. Пользовательский ввод записывается до того, как я инициализирую сегодняшнюю дату во втором jsp (с новой датой () он инициализирует текущее время, которое ПОСЛЕ ввода моего пользователя), поэтому сегодня всегда будет после даты, выбранной пользователем, даже если пользователь выбрал тот же день. Таким образом, мне нужно инициализировать сегодня и сохранить часы/мин/сек/мс на 0.   -  person Kiril    schedule 10.02.2010
comment
Похоже, второй JSP сегодня должен анализировать HTTP-запрос первого JSP, а не вызывать новую дату. Если ответы запутаны, это потому, что ваш вопрос и требования тоже.   -  person duffymo    schedule 10.02.2010
comment
@duffymo Спасибо, буду иметь в виду.   -  person Kiril    schedule 11.02.2010


Ответы (2)


Как ни странно, календарные месяцы считаются от 0 (январь) до 11 (декабрь), поэтому вы передаете «2010-01-09» в formatter.parse() при извлечении поля МЕСЯЦ из календаря.

Это обсуждается в соответствующем вопросе SO.

person martin clayton    schedule 10.02.2010

Если вы не хотите использовать JodaTime, вы можете использовать:

Calendar calendar = Calendar.getInstance();

calendar.set( Calendar.HOUR_OF_DAY, 0 );
calendar.set( Calendar.MINUTE, 0 );
calendar.set( Calendar.SECOND, 0 );
calendar.set( Calendar.MILLISECOND, 0 );

Date today = calendar.getTime();

Это намного эффективнее и менее подвержено ошибкам, чем ваш подход к форматированию/анализу строк.

Если вы можете использовать JodaTime, это гораздо более предпочтительный метод:

LocalDate date = new DateTime().toLocaleDate();
person mtpettyp    schedule 10.02.2010
comment
Спасибо mtpettyp! Выглядит намного лучше, чем то, что было у меня! :) - person Kiril; 11.02.2010