I am not getting clarity on when to use appendZoneId()
and when to use appendZoneOrOffsetId()
in Java’s DateTimeFormatterBuilder
.
In Java, the documentation says both append either ZoneId
or OffsetId
, then what is the difference between appendZoneId()
and appendZoneOrOffsetId()
?
The documentation for appendZoneOrOffsetId() says:
Note that this method is identical to appendZoneId() except in the mechanism used to obtain the zone.
The differences in the mechanism used to obtain the zone are as follows:
- appendZoneId:
“the zone is obtained using a mechanism equivalent to querying the temporal with TemporalQueries.zoneId()” - appendZoneOrOffsetId:
“the zone is obtained using a mechanism equivalent to querying the temporal with TemporalQueries.zone()”
In practice, whether you will see a difference depends on what kind of datetime you are trying to format – whether it contains a zone id or just an offset. Consider the following code:
public static void main(String[] args) {
DateTimeFormatter dtfZ = new DateTimeFormatterBuilder().appendZoneId().toFormatter();
DateTimeFormatter dtfZO = new DateTimeFormatterBuilder().appendZoneOrOffsetId().toFormatter();
tryPrint(ZonedDateTime.now(), dtfZ, "appendZoneId");
tryPrint(ZonedDateTime.now(), dtfZO, "appendZoneOrOffsetId");
tryPrint(OffsetDateTime.now(), dtfZ, "appendZoneId");
tryPrint(OffsetDateTime.now(), dtfZO, "appendZoneOrOffsetId");
}
private static void tryPrint(TemporalAccessor dt, DateTimeFormatter dtf, String description) {
System.out.printf("Trying to format %s using %s:%nt", dt, description);
try {
System.out.println(dtf.format(dt));
} catch (DateTimeException e) {
System.out.println(e);
}
System.out.println();
}
Output:
Trying to format 2024-09-24T13:08:10.042968898+01:00[Europe/London] using appendZoneId:
Europe/London
Trying to format 2024-09-24T13:08:10.045608600+01:00[Europe/London] using appendZoneOrOffsetId:
Europe/London
Trying to format 2024-09-24T13:08:10.046282182+01:00 using appendZoneId:
java.time.DateTimeException: Unable to extract ZoneId from temporal 2024-09-24T13:08:10.046282182+01:00
Trying to format 2024-09-24T13:08:10.046858510+01:00 using appendZoneOrOffsetId:
+01:00
As you can see, if you want to format a datetime with a zone region, then you can use either. But if you only have an offset instead of a region, then you need to use appendZoneOrOffsetId
.
To complicate things further, there is a third method: appendZoneRegionId(). This behaves in a similar way to appendZoneId
, except when you try to format a ZonedDateTime
whose ZoneId
is a ZoneOffset
. A formatter with appendZoneId
will happily append the offset if there is no region, whereas a formatter with appendZoneRegionId
will throw an exception if the ZoneId
is not a ZoneRegion
:
DateTimeFormatter dtfZ = new DateTimeFormatterBuilder().appendZoneId().toFormatter();
DateTimeFormatter dtfZR = new DateTimeFormatterBuilder().appendZoneRegionId().toFormatter();
dtfZ.format(ZonedDateTime.now(ZoneId.of("Europe/London"))); // ok
dtfZ.format(ZonedDateTime.now(ZoneOffset.ofHours(1))); // ok
dtfZR.format(ZonedDateTime.now(ZoneId.of("Europe/London"))); // ok
dtfZR.format(ZonedDateTime.now(ZoneOffset.ofHours(1))); // exception!
2