Appearance
ZonedDateTime
LocalDateTime
always represents local date and time, but to represent a date and time with a time zone, we need ZonedDateTime
.
You can simply think of ZonedDateTime
as LocalDateTime
combined with ZoneId
. ZoneId
is a new time zone class introduced in java.time
, distinct from the old java.util.TimeZone
.
To create a ZonedDateTime
object, you can use several methods, one of which is the now()
method to return the current time:
java
import java.time.*;
public class Main {
public static void main(String[] args) {
ZonedDateTime zbj = ZonedDateTime.now(); // Default time zone
ZonedDateTime zny = ZonedDateTime.now(ZoneId.of("America/New_York")); // Get current time in specified time zone
System.out.println(zbj);
System.out.println(zny);
}
}
When you observe the printed ZonedDateTime
, you’ll find that they have different time zones but represent the same moment (the millisecond difference is due to execution time):
2019-09-15T20:58:18.786182+08:00[Asia/Shanghai]
2019-09-15T08:58:18.788860-04:00[America/New_York]
Another way to create a ZonedDateTime
is by attaching a ZoneId
to a LocalDateTime
, thus converting it to ZonedDateTime
:
java
import java.time.*;
public class Main {
public static void main(String[] args) {
LocalDateTime ldt = LocalDateTime.of(2019, 9, 15, 15, 16, 17);
ZonedDateTime zbj = ldt.atZone(ZoneId.systemDefault());
ZonedDateTime zny = ldt.atZone(ZoneId.of("America/New_York"));
System.out.println(zbj);
System.out.println(zny);
}
}
In this way, the ZonedDateTime
created has the same date and time as the LocalDateTime
, but different attached time zones, thus representing two different moments:
2019-09-15T15:16:17+08:00[Asia/Shanghai]
2019-09-15T15:16:17-04:00[America/New_York]
Time Zone Conversion
To convert time zones, you first need a ZonedDateTime
object. You can then convert the associated time zone to another time zone using withZoneSameInstant()
, which adjusts the date and time accordingly.
The following code demonstrates how to convert Beijing time to New York time:
java
import java.time.*;
public class Main {
public static void main(String[] args) {
// Get current time in China time zone:
ZonedDateTime zbj = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
// Convert to New York time:
ZonedDateTime zny = zbj.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(zbj);
System.out.println(zny);
}
}
It’s important to note that due to daylight saving time, the results of conversions may differ for different dates. Here’s the conversion result for Beijing time on September 15:
2019-09-15T21:05:50.187697+08:00[Asia/Shanghai]
2019-09-15T09:05:50.187697-04:00[America/New_York]
And here’s the conversion result for November 15:
2019-11-15T21:05:50.187697+08:00[Asia/Shanghai]
2019-11-15T08:05:50.187697-05:00[America/New_York]
Notice the 1-hour difference in New York time due to daylight saving.
Note: When dealing with time zones, avoid manually calculating time differences, as this can complicate handling daylight saving time.
With ZonedDateTime
, converting it to local time is straightforward:
java
ZonedDateTime zdt = ...
LocalDateTime ldt = zdt.toLocalDateTime();
This conversion discards the time zone information.
Exercise
A flight from Beijing to New York takes 13 hours and 20 minutes. Calculate the local date and time of arrival in New York based on the departure date and time in Beijing:
java
import java.time.*;
public class Main {
public static void main(String[] args) {
LocalDateTime departureAtBeijing = LocalDateTime.of(2019, 9, 15, 13, 0, 0);
int hours = 13;
int minutes = 20;
LocalDateTime arrivalAtNewYork = calculateArrivalAtNY(departureAtBeijing, hours, minutes);
System.out.println(departureAtBeijing + " -> " + arrivalAtNewYork);
// Test:
if (!LocalDateTime.of(2019, 10, 15, 14, 20, 0)
.equals(calculateArrivalAtNY(LocalDateTime.of(2019, 10, 15, 13, 0, 0), 13, 20))) {
System.err.println("Test failed!");
} else if (!LocalDateTime.of(2019, 11, 15, 13, 20, 0)
.equals(calculateArrivalAtNY(LocalDateTime.of(2019, 11, 15, 13, 0, 0), 13, 20))) {
System.err.println("Test failed!");
}
}
static LocalDateTime calculateArrivalAtNY(LocalDateTime bj, int h, int m) {
return bj; // Implementation needed
}
}
Hint: ZonedDateTime
still provides operations like plusDays()
for adding or subtracting time.
Summary
ZonedDateTime
represents date and time with a time zone, making it useful for time zone conversions.
You can convert between ZonedDateTime
and LocalDateTime
.