Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:


1. Overview

When working with Java applications that handle date and time, understanding how to convert between different types is often essential.

In this tutorial, we’ll explore how to convert between ZonedDateTime and Date in Java.

2. Understanding ZonedDateTime and Date

Before diving into conversions, let’s understand the core concepts of ZonedDateTime and Date in Java. This will help us know when and why to convert between these two types.

2.1. ZonedDateTime

ZonedDateTime is part of the Java Date and Time API introduced in Java 8. A ZonedDateTime object contains:

  • A local date and time (year, month, day, hour, minute, second, nanosecond)
  • A timezone (represented by ZoneId)
  • An offset from UTC/Greenwich

This makes ZonedDateTime incredibly useful for applications that require handling different time zones.

2.2. Date

The Date class is a part of the original date and time API from Java’s early versions. It represents a specific instant in time with millisecond precision beginning from the UNIX epoch (January 1, 1970, 00:00:00 GMT).

Date does not contain any time zone information. It is essentially timezone-agnostic, always representing a point in time in UTC. This can lead to confusion if developers mistakenly interpret Date as representing a time in the local time zone.

3. Converting ZonedDateTime to Date

To convert a ZonedDateTime to a Date, we first need to convert the ZonedDateTime to an Instant, as both ZonedDateTime and Instant represent points on the timeline suitable for conversion. Let’s see how we do it:

public static Date convertToDate(ZonedDateTime zonedDateTime) {
    return Date.from(zonedDateTime.toInstant());

4. Converting Date to ZonedDateTime

Converting back from a Date to a ZonedDateTime also involves getting an Instant from the Date and then specifying the time zone we want the ZonedDateTime to have:

public static ZonedDateTime convertToZonedDateTime(Date date, ZoneId zone) {
    return date.toInstant().atZone(zone);

In this conversion, it’s important to specify the time zone (ZoneId) because a Date object doesn’t contain timezone information. We can get our system’s default ZoneId with the static method ZoneId.systemDefault().

5. Testing Our Methods

Let’s write some unit tests using JUnit to ensure our conversion methods work correctly:

public void givenZonedDateTime_whenConvertToDate_thenCorrect() {
    ZonedDateTime zdt ="UTC"));
    Date date = DateAndZonedDateTimeConverter.convertToDate(zdt);
    assertEquals(Date.from(zdt.toInstant()), date);

public void givenDate_whenConvertToZonedDateTime_thenCorrect() {
    Date date = new Date();
    ZoneId zoneId = ZoneId.of("UTC");
    ZonedDateTime zdt = DateAndZonedDateTimeConverter.convertToZonedDateTime(date, zoneId);
    assertEquals(date.toInstant().atZone(zoneId), zdt);

6. Conclusion

Converting between ZonedDateTime and Date in Java is straightforward once we understand how to handle the conversion points, namely Instant and ZoneId. While ZonedDateTime offers greater functionality and flexibility, Date remains useful in scenarios requiring integration with older Java codebases.

The example code from this article can be found over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

res – REST with Spring (eBook) (everywhere)
Notify of
Inline Feedbacks
View all comments