Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Calendar issue with adding year

I am trying to add a year to date but which is giving the same date for different inputs. Input dates are 28/Feb/2020 and 29/Feb/2020 and output are the same for both of them as 28/Feb/2021. Please help me to find what is wrong here.

Update:

I expect as output as 28/Feb/2021 and 01/Mar/2021.

public static Date dateAdd(Date newDate, int field, int amount) {
        Calendar aCalendar = Calendar.getInstance();
        aCalendar.setTime(newDate);
        aCalendar.add(field, amount);
        return aCalendar.getTime();
    }

    public static void main(String[] args) throws Exception {

        System.out.println(dateAdd(new SimpleDateFormat("dd/MM/yyyy").parse("28/02/2020"),Calendar.YEAR,1));
        System.out.println(dateAdd(new SimpleDateFormat("dd/MM/yyyy").parse("29/02/2020"),Calendar.YEAR,1));

        // Console output below

        //Sun Feb 28 00:00:00 IST 2021
        //Sun Feb 28 00:00:00 IST 2021
    }
like image 484
sunleo Avatar asked Sep 10 '26 02:09

sunleo


2 Answers

After going through documentation of add and roll. It is clear that what you are looking for is to be found in roll not add.

Further after some research on the topic I found that the given scenario is also to be business dependent and depends what do you want to do because the add and roll gives you the choice to choose either of these.

I found this while searching for the similar problem I had.

Coming back to your code following modification is needed

aCalendar.roll(field, amount);

Someone more expert here will be able to help clean up this answer. JavaDocs for me were not very clear for these so the following question has some interesting answers to it

like image 78
DevX Avatar answered Sep 12 '26 14:09

DevX


There is no reason to expect a result of 01/Mar/2021. Indeed, some would then question why adding a year to the two dates 29/Feb/2020 and 01/Mar/2020 would output the same result of 01/Mar/2021 for both of them !

Instead, Java follows a clear, consistent and simple rule : If the result of date arithmetic (such as adding months or years) results in an invalid date, then the answer returned will be the last day of that result’s month.

Eg, from : https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html#plusMonths-long-

  1. Add the input months to the month-of-year field
  2. Check if the resulting date would be invalid
  3. Adjust the day-of-month to the last valid day if necessary

For example, 2007-03-31 plus one month would result in the invalid date 2007-04-31. Instead of returning an invalid result, the last valid day of the month, 2007-04-30, is selected instead.

like image 28
racraman Avatar answered Sep 12 '26 15:09

racraman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!