2014-11-04 3 views
2

Я хочу получить последний месяц Конечная дата, я получаю текущий месяц и возвращаю его на один и устанавливаю значение месяца. Но Calender.set (Calender.Month, lastMonth) не работает только для определенной даты.Calender.set() Не работает должным образом

public static String getLastMonthEndDate(Date nowDate, String dateFormat) 
{ 
    final String METHOD_NAME = "getLastMonthEndDate" ; 


    SimpleDateFormat formatedDate = new SimpleDateFormat(dateFormat); 


    Calendar calendar = new GregorianCalendar(2014, Calendar.OCTOBER, 31); // Hard coded as 2014, oct 31st for the sake of example. 
    //calendar.setTime(nowDate); 
    System.out.println(calendar.getTime()); 
    if(calendar.get(Calendar.MONTH) == Calendar.JANUARY) 
    { 
     calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 1); 
    } 

    //System.out.println("calendar.get(Calendar.MONTH) -1 : " + (calendar.get(Calendar.MONTH) -1)); 
    int lastMonth = (calendar.get(Calendar.MONTH) -1); 
    System.out.println("Last month : "+lastMonth); 
    calendar.set(Calendar.MONTH, lastMonth); 
    //System.out.println(calendar.getTime()); 
    //System.out.println("(calendar.get(Calendar.MONTH) : " + calendar.get(Calendar.MONTH)); 
    System.out.println("calendar.getActualMaximum(Calendar.DAY_OF_MONTH) : " + calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); 

    calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); 
    System.out.println("calendar.getTime() : " + calendar.getTime()); 

    return formatedDate.format(calendar.getTime()); 
} 



public static void main(String[] args) 
{ 

    Date dCurrentDate = getCurrentDate(); 
    String strLastMonthEndDateInYYYY = getLastMonthEndDate(dCurrentDate, "MM/dd/yyyy"); 
    System.out.println("strLastMonthEndDateInYYYY : "+strLastMonthEndDateInYYYY); 

} 

Внизу вывод, который я получил

output : 


Fri Oct 31 00:00:00 IST 2014 

Last month : 8 

calendar.getActualMaximum(Calendar.DAY_OF_MONTH) : 31 

calendar.getTime() : Wed Oct 01 00:00:00 IST 2014 

strLastMonthEndDateInYYYY : 10/01/2014 

Я не знаю, что где ошибка. Пожалуйста помоги.

+0

Возможно, вы должны смотреть на [это] (http://stackoverflow.com/questions/4931955/why-java-calendar-setint-year- int-month-int-date-not-return-correct-date) – ha9u63ar

+0

@hagubear Не имеет значения, так как Calendar.OCTOBER - это всего лишь 9. Так как 0 представляет январь. – codeMan

+0

Почему вы не используете Calendar.add (Calendar.Month, -1), чтобы вычесть месяц? Тогда вам не нужно делать арифметику года для себя. –

ответ

5

Это не работает, потому что вы устанавливаете дату «09/31/2014» после операций в календаре, а в сентябре 2014 года нет 31-го дня. По умолчанию java Calendar - lenient и будет интерпретировать это дата как «10/01/2014» (1 октября 2014 года).

Здесь relevant part of the Javadoc:

Когда календарь находится в режиме мягкого, он принимает более широкий диапазон значений календаря поля, чем она производит. Когда календарь пересчитывает значения поля календаря для возврата методом get(), все поля календаря нормализуются. Например, снисходительное GregorianCalendar интерпретирует МЕСЯЦ == января DAY_OF_MONTH == 32 в феврале 1.

А вот прокомментированную версию соответствующих частей коды, чтобы объяснить, что происходит:

Calendar calendar = new GregorianCalendar(2014, Calendar.OCTOBER, 31); // 10/31/2014 
// [...] 
int lastMonth = (calendar.get(Calendar.MONTH) -1); // lastMonth will be Calendar.SEPTEMBER 
calendar.set(Calendar.MONTH, lastMonth); // internal value of the calendar is now 09/31/2014 
// [..] 
System.out.println("calendar.getActualMaximum(Calendar.DAY_OF_MONTH) : " + calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); // returns 31 because this is a get() method, so 09/31/2014 will be converted to 10/01/2014, and there are 31 days in October (but the internal representation of the calendar will still be 09/31/2014) 
// [...] 
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); // internal representation is still 09/31/2014, so this will not change the value 
// [...] 
return formatedDate.format(calendar.getTime()); // this is a get() method, so the value will be converted to 10/01/2014 

Лучшим решением было бы установить ваш Calendar в первый день месяца, и вычесть один день:

Calendar calendar = new GregorianCalendar(2014, 9, 31); 
calendar.set(Calendar.DAY_OF_MONTH, 1); 
calendar.add(Calendar.DAY_OF_MONTH, -1); 
System.out.println((new SimpleDateFormat("MM/dd/yyyy")).format(calendar.getTime())); // 09/30/2014 
+0

Где я устанавливаю 31 в сентябре 2014 года? – codeMan

+0

@codeMan Отредактировал мой ответ, чтобы показать вам, где вы неправильно настраиваете календарь. –

+0

да последняя строка возвращает 31, потому что она находится в октябре.Если это так, выход должен был быть '10/31/2014', но почему это' 10/01/2014' – codeMan

1

Ну причина я могу видеть вас установить дату ур как:

Calendar calendar = new GregorianCalendar(2014, 9, 31); 

Если вы посмотрите на календарь, то 9-й месяц (сентябрь) имеет только 30 дней. Таким образом, ваша дата автоматически устанавливается равным (2014/10/1) вместо (2014,9,31)

+1

№ октябрь представлен 9. С января начинается с 0. – codeMan

+0

http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#MONTH говорит, что он прав – ha9u63ar

1

Вы можете использовать Calendar.add (Calendar.Month, -1) , чтобы добраться до preveous месяц и установить максимальный день этого месяца.

как:

public static Date getLastMonthLastDate() { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.add(Calendar.MONTH, -1); 

    int max = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); 
    calendar.set(Calendar.DAY_OF_MONTH, max); 

    return calendar.getTime(); 
} 

Более here

Смежные вопросы