0

i need to write a code that takes in input an integer called mese(this int goes from 0 to 5), this integer will be added to the current month, that becouse call this function when i need to get the last day of an exact month example, it's august and i need to know the last day of august + mese where mese =3 so i need to know the last day of august+3= november, so the function will return 30 in this case. here is my code, but i don't understand what's wrong(note that this is just a part of my real code)

public int getmax(int mese){
    int res =0;
    int giornocorr = Calendar.getInstance().get(Calendar.DATE);
    int mesecorr = Calendar.getInstance().get(Calendar.MONTH);
    int annocorr = Calendar.getInstance().get(Calendar.YEAR);
if ((mesecorr + 1) - mese == 0) {
        // se siamo nel mese corrente
        giornoFineMese = Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);
        res = giornoFineMese - giornocorr;
        System.out.println("days of this month: " + res);
    } else {
        // se non siamo nel mese corrente
        Calendar c = Calendar.getInstance();
        if ((mesecorr + 1 + mese) % 13 >= mesecorr) {// current year
            c.set(Calendar.MONTH, mesecorr + 1 + mese);
            c.set(Calendar.YEAR, annocorr);
        } else {// next year
            c.set(Calendar.MONTH, mesecorr + 1 + mese);
            c.set(Calendar.YEAR, annocorr + 1);
        }
        c.add(Calendar.MONTH, mese);
        c.set(Calendar.DATE, c.getMaximum(Calendar.DATE));
        res = c.getActualMaximum(Calendar.DATE);
        System.out.println("days of month " +c.get(Calendar.MONTH)+" "+ res);
        return res;
    }

thanks to anyone who answers

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
pietro
  • 51
  • 8
  • If you must use `Calendar` (not recommended) see this: [last day of month calculation](https://stackoverflow.com/questions/9397203/last-day-of-month-calculation/33866752). Much better would be to use the modern Java `time` classes - for example: `LocalDate lastDay = now.with(TemporalAdjusters.lastDayOfMonth());` - see [here](https://stackoverflow.com/a/33866752/12567365) for an example. – andrewJames Aug 23 '21 at 16:12
  • 1
    Why not `int max = LocalDate.now().plusMonths(mese).lengthOfMonth();` – Oboe Aug 23 '21 at 16:14
  • does it work even if i add a nymber of months that could change the year?or i have to edit the code in case of new year? – pietro Aug 23 '21 at 18:24
  • 1
    I recommend you don’t use `Calendar`. That class is poorly designed and long outdated. Instead use `YearMonth` and/or `LocalDate`; both are from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Aug 23 '21 at 19:16

2 Answers2

3

java.time

Since the month doesn’t change at the same point in all time zones, you need to decide a time zone for current month. Like @g00se I recommend that you use java.time, the modern Java date and time API, for your date work.

private static final ZoneId ZONE = ZoneId.of("Europe/Rome");

/**
 * @param mese Number of months to add to current month, 0 through 5
 * @return day number of the last day of the month mese months from now
 */
public int getmax(int mese) {
    if (mese < 0 || mese > 5) {
        throw new IllegalArgumentException("mese era " + mese);
    }
    return YearMonth.now(ZONE).plusMonths(mese).lengthOfMonth();
}

Let’s try it out with your example. Now is August. In 3 months it will be November. The last day of November is 30th. So we expect 30 from the following call:

    int max = getmax(3);
    System.out.format(
            "In 3 months from now the last day of the month will be %d%n", max);            

Output is:

In 3 months from now the last day of the month will be 30

A YearMonth is a year and a month like August 2021 or November 2021 or January 2022. So adding months works across New Year too, you get the expected month in the following year (or several years ahead if you add more than 12 months, for example). Let’s also try your example from the comment, adding 5 months and expecting January 2022 and hence 31 days:

    int max = getmax(5);
    System.out.format(
            "In 5 months from now the last day of the month will be %d%n", max);

In 5 months from now the last day of the month will be 31

Link

Oracle tutorial: Date Time explaining how to use java.time.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
1

You could use YearMonth. Please test:

import java.time.*;

public class NumDays {
    public static void main(String[] args) {
        try {
            ZonedDateTime zdt = ZonedDateTime.now();
            // TEST LEAP YEAR
            zdt = zdt.plusYears(2);
            System.out.printf("Is %s a leap year? %b%n", zdt, Year.isLeap(zdt.getYear()));
            YearMonth startMonth = YearMonth.of(zdt.getYear(), Integer.parseInt(args[0]));
            int plusMonths = Integer.parseInt(args[1]);
            YearMonth endMonth = startMonth.plusMonths(plusMonths);
            int endDays = endMonth.lengthOfMonth();
            System.out.println(zdt);
            System.out.printf("%s plus %d month(s) is month %s, which has max of %d days", startMonth, plusMonths, endMonth, endDays);
        }
        catch(Throwable t) {
            t.printStackTrace();
        }
    }
}
g00se
  • 3,207
  • 2
  • 5
  • 9
  • thank you, but what am i supposed to pass in input? if i understood i have to pass the current month and the numberof months that i want to add, right? it returns Number FormatException – pietro Aug 23 '21 at 18:27
  • Both month numbers – g00se Aug 23 '21 at 18:29