The old, much-derided Date and Calendar classes have always been confusing and error-prone, particularly in a
multi-threaded context. Starting from Java SE 8, the built-in java.time (JSR-310) API provides a modern, immutable, and thread-safe
framework that addresses these long-standing design flaws.
This applies not only to java.util.Date and java.util.Calendar, but also to their JDBC counterparts
java.sql.Date and java.sql.Time, which inherit the same design problems and should be replaced with java.time
types when interacting with modern JDBC drivers (JDBC 4.2+).
Note: While Joda-Time remains the standard for handling date and time in java versions prior to 8, users of newer versions should
consider migration to the java.time API.
The java.time package offers specific classes for:
| Class | Use for |
|---|---|
|
Instant |
a timestamp |
|
LocalDate |
a date, without time of day, offset, or zone |
|
LocalTime |
the time of day, without date, offset, or zone |
|
LocalDateTime |
the date and time, without offset, or zone |
|
OffsetTime |
the time of day with an offset such as +02:00, without date, or zone |
|
OffsetDateTime |
the date and time with an offset such as +02:00, without a zone |
|
ZonedDateTime |
the date and time with a time zone and offset |
|
Year |
a year |
|
YearMonth |
a year and month |
|
MonthDay |
month and day |
|
Month/DayOfWeek |
enum classes for date fields |
|
Period |
a date-based amount of time, such as "2 months and 3 days" |
|
Duration |
a time-based amount of time, such as "34.5 seconds" |
|
Clock |
a clock providing access to the current instant, date and time |
Use the java.time API instead of java.util.Calendar, java.util.Date, java.sql.Date, or
java.sql.Time.
java.sql.Timestamp is excluded from this rule because it may still be required for compatibility with older JDBC drivers that do not
support the java.time types introduced in JDBC 4.2.
Use of java.util.Date, java.util.Calendar, java.sql.Date, or java.sql.Time
Date now = new Date(); // Noncompliant
DateFormat df = new SimpleDateFormat("dd.MM.yyyy");
Calendar christmas = Calendar.getInstance(); // Noncompliant
christmas.setTime(df.parse("25.12.2020"));
java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis()); // Noncompliant
java.sql.Time sqlTime = new java.sql.Time(System.currentTimeMillis()); // Noncompliant
LocalDate nowUTC = LocalDate.now(ZoneOffset.UTC); // gets current date in UTC
LocalDate christmas = LocalDate.of(2020, Month.DECEMBER, 25); // create date from year/month/day
ZonedDateTime nowParis = ZonedDateTime.now(ZoneId.of("Europe/Paris")); // get current time in Paris with time-zone information
LocalDate sqlDate = LocalDate.now(); // use LocalDate instead of java.sql.Date
LocalTime sqlTime = LocalTime.now(); // use LocalTime instead of java.sql.Time
java.sql.Timestamp timestamp = new java.sql.Timestamp(System.currentTimeMillis()); // Compliant - exception for legacy JDBC compatibility