Converting Between Legacy and New Date Classes
New code should use java.time, but older libraries and databases still use java.util.Date, Calendar, java.sql.Date, java.sql.Timestamp and TimeZone. To connect the two worlds, Java 8 added bridge methods to the legacy classes, such as date.toInstant() and Date.from(instant). In this lesson, you will learn how to convert in both directions, so you can keep your own code in java.time and convert only at the edges.
Conversion Methods
| From | To | Method |
|---|---|---|
java.util.Date | Instant | date.toInstant() |
Instant | java.util.Date | Date.from(instant) |
Calendar | Instant | calendar.toInstant() |
GregorianCalendar | ZonedDateTime | gc.toZonedDateTime() |
ZonedDateTime | GregorianCalendar | GregorianCalendar.from(zdt) |
TimeZone | ZoneId | timeZone.toZoneId() |
ZoneId | TimeZone | TimeZone.getTimeZone(zoneId) |
java.sql.Date | LocalDate | sqlDate.toLocalDate() |
LocalDate | java.sql.Date | java.sql.Date.valueOf(localDate) |
java.sql.Timestamp | LocalDateTime | ts.toLocalDateTime() |
LocalDateTime | java.sql.Timestamp | Timestamp.valueOf(ldt) |
A java.util.Date is an instant, so converting it to a LocalDate needs a time zone: date.toInstant().atZone(zone).toLocalDate().
Example: Converting Both Ways
Let's see an example that converts a legacy Date and back.
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class Bridge {
public static void main(String[] args) {
Date legacy = new Date(1_794_490_200_000L);
Instant instant = legacy.toInstant();
System.out.println("Instant: " + instant);
ZoneId india = ZoneId.of("Asia/Kolkata");
LocalDate local = instant.atZone(india).toLocalDate();
System.out.println("LocalDate: " + local + " in " + india);
Date back = Date.from(instant);
System.out.println("Round trip equal? " + back.equals(legacy));
GregorianCalendar cal = GregorianCalendar.from(instant.atZone(india));
System.out.println("Calendar hour: " + cal.get(Calendar.HOUR_OF_DAY));
ZonedDateTime zdt = cal.toZonedDateTime();
System.out.println("From calendar: " + zdt);
System.out.println("TimeZone to ZoneId: "
+ TimeZone.getTimeZone("Europe/London").toZoneId());
}
}Instant: 2026-11-12T13:30:00Z
LocalDate: 2026-11-12 in Asia/Kolkata
Round trip equal? true
Calendar hour: 19
From calendar: 2026-11-12T19:00+05:30[Asia/Kolkata]
TimeZone to ZoneId: Europe/LondonExplanation: The Date is a moment in time, so toInstant() gives the same moment as an Instant. To get a LocalDate, a zone must be chosen. Date.from converts back with no loss. GregorianCalendar.from and toZonedDateTime convert between calendars and zoned date-times.
Example: JDBC Dates
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
public class SqlDates {
public static void main(String[] args) {
java.sql.Date sqlDate =
java.sql.Date.valueOf(LocalDate.of(2026, 11, 12));
System.out.println("sql.Date: " + sqlDate);
System.out.println("Back to LocalDate: " + sqlDate.toLocalDate());
Timestamp ts = Timestamp.valueOf(LocalDateTime.of(2026, 11, 12, 9, 30));
System.out.println("Timestamp: " + ts);
System.out.println("Back to LocalDateTime: " + ts.toLocalDateTime());
}
}sql.Date: 2026-11-12
Back to LocalDate: 2026-11-12
Timestamp: 2026-11-12 09:30:00.0
Back to LocalDateTime: 2026-11-12T09:30Explanation: java.sql.Date and Timestamp have direct conversions to and from LocalDate and LocalDateTime. Modern JDBC drivers can also read and write java.time types directly with getObject(column, LocalDate.class) and setObject, covered later in the course.
Common Mistakes
Calling date.toLocalDate(). java.util.Date has no such method; go through toInstant().atZone(zone).
Using the system default zone without thinking. ZoneId.systemDefault() differs between servers; choose the zone deliberately.
Mixing up java.util.Date and java.sql.Date. java.sql.Date represents only a date and has toLocalDate().
Practice
- Easy: Convert
new Date()into aLocalDateTimein your own time zone and print it. - Harder: Write two helper methods,
toLocalDate(Date d, ZoneId z)andtoDate(LocalDate ld, ZoneId z), that convert at midnight in the given zone, and test a round trip.
Key Takeaways
Was this tutorial helpful?