Java : Don't use the legacy Date and Calendar classes, use new APIs instead

There are new date/time APIs added since Java 8. e.g. Instant, LocalTime, LocalDate, LocalDateTime, ZonedDateTime, etc. The new APIs are improvements to legacy APIs such as the Date class, the Calendar class.

Note:


Feature comparison between new APIs and old APIs

The main API for dates, times, instants, and durations.

There are new Date and Time APIs in the java.time package.

Class Instantaneous point Date Time Time-zone Immutable Thread-safe
New APIs Instant
LocalDate
LocalTime
LocalDateTime
ZonedDateTime
ZoneId
Old APIs Date
Calendar
TimeZone

The features of the new APIs separate smaller than the old APIs. And the new APIs are clarified whether they have a time-zone or not.

The LocalDate class can be used if only the date is used, and the LocalTime class if only the time is used. You use the LocalDateTime class if you don't need a time-zone. In the old APIs, everything was the Calendar class.

It's a basic design principle to keep classes with as few features as possible. Additionally, the new APIs are immutable objects. It's also thread-safe.

Basics of the new APIs

There is the related post below. Please see it.

A brief introduction to the old APIs

Date

The class Date represents a specific instant in time, with millisecond precision.

The Date class is equivalent to the Instant class in the new APIs. This class had calendar functionality in Java 1.0, but was deprecated in Java 1.1.

Calendar

The Calendar class is an abstract class that provides methods for converting between a specific instant in time and a set of calendar fields such as YEAR, MONTH, DAY_OF_MONTH, HOUR, and so on, and for manipulating the calendar fields, such as getting the date of the next week.

The Calendar class is equivalent to the ZonedDateTime class in the new APIs.

TimeZone

TimeZone represents a time zone offset, and also figures out daylight savings.

The TimeZone class is equivalent to the ZoneId class and the ZoneOffset class in the new APIs.

Interoperability

Some older APIs may require the legacy class as a parameter. It's okay when it's like that. You can convert between the old APIs and new APIs.

Old APIs to New APIs

// Date(old API) → Instant(new API)
final var date = new Date(4102444800123L);
System.out.println(date.getTime()); // 4102444800123

final var instant = date.toInstant();
System.out.println(instant); // 2100-01-01T00:00:00.123Z
System.out.println(instant.getEpochSecond()); // 4102444800
System.out.println(instant.getNano()); // 123000000
// TimeZone(old API) → ZoneId(new API)
final var timeZone = TimeZone.getDefault();
System.out.println(timeZone.getID()); // America/Los_Angeles

final var zoneId = timeZone.toZoneId();
System.out.println(zoneId); // America/Los_Angeles
// Calendar(old API) → ZonedDateTime(new API)
final var calendar = Calendar.getInstance();
calendar.setTimeInMillis(4102444800000L);
System.out.printf("%tc%n", calendar); // Thu Dec 31 16:00:00 PST 2099

final var instant = calendar.toInstant();
System.out.println(instant); // 2100-01-01T00:00:00Z

final var zoneId = calendar.getTimeZone().toZoneId();
System.out.println(zoneId); // America/Los_Angeles

final var zonedDateTime = ZonedDateTime.ofInstant(instant, zoneId);
System.out.println(zonedDateTime); // 2099-12-31T16:00-08:00[America/Los_Angeles]

New APIs to Old APIs

// Instant(new API) → Date(old API)
final var instant = Instant.ofEpochSecond(4102444800L, 123456789L);
System.out.println(instant); // 2100-01-01T00:00:00.123456789Z

final var date = Date.from(instant);

// Digits less than milliseconds are truncated.
System.out.println(date.getTime()); // 4102444800123
// ZoneId(new API) → TimeZone(old API)
final var zoneId = ZoneId.systemDefault();
System.out.println(zoneId); // America/Los_Angeles

final var timeZone = TimeZone.getTimeZone(zoneId);
System.out.println(timeZone.getID()); // America/Los_Angeles
// ZonedDateTime(new API) -> Calendar(old API)
final var zonedDateTime = ZonedDateTime.of(
        2099, 12, 31, 16, 0, 0, 0, ZoneId.systemDefault());
System.out.println(zonedDateTime); // 2099-12-31T16:00-08:00[America/Los_Angeles]

final var instant = zonedDateTime.toInstant();
System.out.println(instant); // 2100-01-01T00:00:00Z

final var timeZone = TimeZone.getTimeZone(zonedDateTime.getZone());
System.out.println(timeZone.getID()); // America/Los_Angeles

final var calendar = Calendar.getInstance(timeZone);
calendar.setTime(Date.from(instant));

System.out.printf("%tc%n", calendar); // Thu Dec 31 16:00:00 PST 2099

Conclusion

This article was a quick introduction to the comparison between the new Date and Time APIs and the old APIs.

You may be tempted to use the old APIs you are familiar with. However, the new APIs were created because there was a problem with the old APIs. There should have been some improvements.

This article recommends using the new APIs.


Related posts

To top of page