Reputation: 577
The following snippet returns:
28
31
I can't figure out, why. I tried so set the calendar object to Feb 2021 in two ways, what am I doing wrong? Month is zero-based, so Feb is "1".
import java.util.Calendar;
import java.util.GregorianCalendar;
public class HelloWorld{
public static void main(String []args){
Calendar g = new GregorianCalendar(2021, 1, 28);
System.out.println(g.getActualMaximum(Calendar.DAY_OF_MONTH));
int year = 2021;
int month = 1;
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
System.out.println(c.getActualMaximum(Calendar.DAY_OF_MONTH));
}
}
Or does this only happen, because I call Calendar.getInstance() on March 29, 30 or 31 and I don't call
c.set(Calendar.DAY_OF_MONTH, {any day below 29});
Upvotes: 1
Views: 1410
Reputation: 79075
java.util
date-time API and their formatting API, SimpleDateFormat
are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API* .
Using modern date-time API:
import java.time.Month;
import java.time.Year;
public class Main {
public static void main(String[] args) {
System.out.println(YearMonth.of(2021, Month.FEBRUARY).lengthOfMonth());
}
}
Output:
28
Learn more about the modern date-time API from Trail: Date Time.
Using legacy API:
import java.util.Calendar;
import java.util.GregorianCalendar;
public class Main {
public static void main(String[] args) {
// 1st Feb 2021
Calendar cal = new GregorianCalendar(2021, Calendar.FEBRUARY, 1);
System.out.println(cal.getActualMaximum(Calendar.DAY_OF_MONTH));
}
}
Output:
28
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Upvotes: 6
Reputation: 159086
You call Calendar.getInstance()
, which returns a Calendar
object initialized to the current time, which today means Mar 31, 2021.
You then set YEAR
to 2021 and MONTH
to 1 (Feb), leaving DAY_OF_MONTH
at 31. If you asked the Calendar
object for the date, it would resolve the fields and return a date value that explains the issue:
System.out.println(c.getTime()); // prints: Wed Mar 03 11:51:55 EST 2021
See how it says Mar 3, 2021? That is because Feb 31 rolls over after Feb 28 and becomes Mar 3.
Since the Calendar
object is now in March, the c.getActualMaximum(Calendar.DAY_OF_MONTH)
correctly returns 31.
To do it right, call clear()
and set DAY_OF_MONTH
to 1, which is much easier when you use the nice set(year, month, date)
helper method.
int year = 2021;
int month = Calendar.FEBRUARY/*1*/;
Calendar c = Calendar.getInstance();
c.clear();
c.set(year, month, 1);
System.out.println(c.getTime()); // prints: Mon Feb 01 00:00:00 EST 2021
System.out.println(c.getActualMaximum(Calendar.DAY_OF_MONTH)); // prints: 28
Upvotes: 5