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:
- This article may use translation software for your convenience. Please also check the original Japanese version.
Feature comparison between new APIs and old APIs
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 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 equivalent to the ZonedDateTime class in the new APIs.
TimeZone
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
- API Examples
- Calendar
- ChronoLocalDate
- ChronoLocalDateTime
- ChronoZonedDateTime
- Clock
- Date
- DateTimeException
- DateTimeParseException
- DayOfWeek
- Duration
- Era
- Instant
- InstantSource
- JapaneseDate
- LocalDate
- LocalDateTime
- LocalTime
- Month
- MonthDay
- OffsetDateTime
- OffsetTime
- Period
- Temporal
- TemporalAccessor
- TemporalAdjuster
- TemporalAdjusters
- TimeZone
- Year
- YearMonth
- ZonedDateTime
- ZoneId
- ZoneOffset