Search code examples
javajodatime

dayOfMonth(31) in Month.AUGUST


Following code calculates the exact date when a child graduates from Kindergarden. Its always the 31th August after the 6th birthday. dob is the child´s birthday :

public static DateMidnight getKigaAustritt(DateMidnight dob){
    DateMidnight sechs = dob.plus(Period.years(6));
    DateMidnight austritt = new DateMidnight(sechs);
    if (sechs.getMonthOfYear() > Month.AUGUST){
        austritt = sechs.withYear(sechs.getYear()+1);
        austritt = sechs.withMonthOfYear(Month.AUGUST);
        austritt = sechs.withDayOfMonth(31);
    }else{
        austritt = sechs.withMonthOfYear(Month.AUGUST);
        austritt = sechs.withDayOfMonth(31);
    }
    return austritt;
}

Now, if i leave it at that, the method is called from elsewhere and i invariably get an error stating that dayOfMonth() has to be in the range [1,30]. If i change the code to ..withDayOfMonth(30) the program works fine, but graduates the child a day earlier. Now, MonthOfYear beeing August, i wonder why this is happening. Any hints?


Solution

  • The problem is that the month for 'sechs' is not being set. This is because you are calling sechs.withMonthOfYear but assigning this to austritt. withMonthOfYear returns a modified copy, it does not modify the element on which it is called. Consider the following:

    austritt = sechs.withYea(...)
                    .withMonthOfYear(...)
                    .withDayOfMonth(...);
    

    Per API

    Returns a copy of this date with the day of month field updated.

    DateMidnight is immutable, so there are no set methods. Instead, this method returns a new instance with the value of day of month changed.