Date Field Value Out Of Range
ID |
java.invalid_date_values |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Code Smell |
Language |
Java |
Tags |
code-style, date-time |
Description
Reports an integer literal outside the valid range for a java.util.Date / java.sql.Date
field, in three call shapes:
-
a
Datesetter:setMonth,setDate,setHours,setMinutes,setSeconds; -
a
new GregorianCalendar(year, month, day[, hour, minute[, second]])constructor call; -
Calendar.set(Calendar.FIELD, value), orCalendar.get(Calendar.FIELD)compared with==or!=against a literal.
Rationale
None of these throws or warns when the value is out of range — the date silently rolls.
d.setMonth(12) does not fail; it produces January of the following year, because month is
zero-based (0-11) while a caller reasoning in calendar terms writes 12 for December. Each
field’s valid range starts at a different number for a different reason, which is exactly why
copying one field’s bound to another is the recurring mistake:
| Field | Valid range |
|---|---|
month |
0-11 |
day of month |
1-31 |
hour |
0-23 |
minute |
0-59 |
second |
0-61 (a leap second may push it to 61) |
Date d = new Date();
d.setMonth(12); // rolls into January of the next year
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 12); // same mistake through Calendar
new GregorianCalendar(2014, 12, 25); // month out of range in the constructor
Not checked, matching the underlying defect definition: invalid leap years, leap seconds (second 61 is accepted, not flagged), and the 31st of a 30-day month.
Only literal arguments are decidable; a variable or a computed expression is left alone
rather than guessed at. The Calendar field constant must be written qualified
(Calendar.MONTH or java.util.Calendar.MONTH) — a bare field name reaching a Calendar
constant only through a static import is a known limitation and is not recognised.
Remediation
Use the zero-based (or one-based, for day) value that matches the field’s own convention.
Date d = new Date();
d.setMonth(11); // December
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 11);
new GregorianCalendar(2014, 11, 25);