Just out of curiosity, why shouldn't I be able to compare time zones?
One timezone could be -2:00 related to UTC while another one would be +2:00 for example. Why not consider those as -2:00 < +2:00 and so on?
Just out of curiosity, why shouldn't I be able to compare time zones?
One timezone could be -2:00 related to UTC while another one would be +2:00 for example. Why not consider those as -2:00 < +2:00 and so on?
Since ZoneId encode Time Zones and it change the offset respect UTC, there is not an order.
That's why ZoneOffset implements Comparable<ZoneOffset> since it is a fixed offset.
(Additional note)
For example:
Canada/Newfoundland -02:30/-03:30 ~ America/Belem -03:00/-03:00
where sometimes the order of Newfoundland ~ Belem is -02:30 > -03:00 but sometimes is -03:30 < -03:00.
A simple way to list all (from now up to four years) zone id pairs where the offset order change from A < B to B < A could be:
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
public class ZoneIdOrderChanges {
public static void main(String... args) {
// all zones
List<ZoneId> zonesId = ZoneId.getAvailableZoneIds().stream().map(ZoneId::of).collect(toList());
// all combinations two by two without repetition
final List<Tuple<ZoneId, ZoneId>> pairs = IntStream.range(1, zonesId.size()).boxed().flatMap(a ->
IntStream.range(a + 1, zonesId.size()).mapToObj(b ->
new Tuple<>(zonesId.get(a), zonesId.get(b)))).collect(toList());
// from now up to 4 years after now
OffsetDateTime t0 = OffsetDateTime.now();
OffsetDateTime t = OffsetDateTime.now();
OffsetDateTime sentry = t.plus(4, ChronoUnit.YEARS);
BiFunction<OffsetDateTime, Integer, Integer> compareZones = (d, i) ->
Integer.compare(ZonedDateTime.ofInstant(d.toInstant(), pairs.get(i).a).getOffset()
.compareTo(ZonedDateTime.ofInstant(d.toInstant(), pairs.get(i).b).getOffset()), 0);
Function<OffsetDateTime, int[]> forder = z -> IntStream
.range(0, pairs.size())
.map(i -> compareZones.apply(z, i))
.toArray();
int[] order = forder.apply(t);
Set<String> examples = new HashSet<>();
while (t.compareTo(sentry) <= 0) {
int[] o = forder.apply(t);
if (Arrays.compare(order, o) != 0) {
for (int i = 0; i < o.length; i++)
// only interested in not equals cases
if (order[i] != o[i] && order[i] != 0 && o[i] != 0) {
final OffsetDateTime tt = t;
String example = Stream.of(pairs.get(i).a, pairs.get(i).b)
.map(z -> String.format("%s %s/%s",
z.getId(),
ZonedDateTime.ofInstant(t0.toInstant(), z).getOffset(),
ZonedDateTime.ofInstant(tt.toInstant(), z).getOffset()))
.collect(joining(" ~ "));
if (!examples.contains(example)) {
examples.add(example);
System.out.println(example);
}
}
}
t = t.plus(1, ChronoUnit.DAYS);
}
}
@Getter
@Setter
@AllArgsConstructor
static class Tuple<A, B> {
private A a;
private B b;
}
}
with output (for that time interval and current rules)
Asia/Yerevan +04:00/+04:00 ~ Iran +04:30/+03:30
Asia/Yerevan +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Etc/GMT-4 +04:00/+04:00 ~ Iran +04:30/+03:30
Etc/GMT-4 +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Asia/Dubai +04:00/+04:00 ~ Iran +04:30/+03:30
Asia/Dubai +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Indian/Reunion +04:00/+04:00 ~ Iran +04:30/+03:30
Indian/Reunion +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Indian/Mauritius +04:00/+04:00 ~ Iran +04:30/+03:30
Indian/Mauritius +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Europe/Saratov +04:00/+04:00 ~ Iran +04:30/+03:30
Europe/Saratov +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Europe/Samara +04:00/+04:00 ~ Iran +04:30/+03:30
Europe/Samara +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Indian/Mahe +04:00/+04:00 ~ Iran +04:30/+03:30
Indian/Mahe +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Asia/Baku +04:00/+04:00 ~ Iran +04:30/+03:30
Asia/Baku +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Asia/Muscat +04:00/+04:00 ~ Iran +04:30/+03:30
Asia/Muscat +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Europe/Volgograd +04:00/+04:00 ~ Iran +04:30/+03:30
Europe/Volgograd +04:00/+04:00 ~ Asia/Tehran +04:30/+03:30
Iran +04:30/+03:30 ~ Europe/Astrakhan +04:00/+04:00
Iran +04:30/+03:30 ~ Asia/Tbilisi +04:00/+04:00
Iran +04:30/+03:30 ~ Europe/Ulyanovsk +04:00/+04:00
Asia/Tehran +04:30/+03:30 ~ Europe/Astrakhan +04:00/+04:00
Asia/Tehran +04:30/+03:30 ~ Asia/Tbilisi +04:00/+04:00
Asia/Tehran +04:30/+03:30 ~ Europe/Ulyanovsk +04:00/+04:00
Pacific/Fakaofo +13:00/+13:00 ~ NZ-CHAT +12:45/+13:45
Pacific/Fakaofo +13:00/+13:00 ~ Pacific/Chatham +12:45/+13:45
NZ-CHAT +12:45/+13:45 ~ Pacific/Enderbury +13:00/+13:00
NZ-CHAT +12:45/+13:45 ~ Pacific/Tongatapu +13:00/+13:00
NZ-CHAT +12:45/+13:45 ~ Etc/GMT-13 +13:00/+13:00
Pacific/Chatham +12:45/+13:45 ~ Pacific/Enderbury +13:00/+13:00
Pacific/Chatham +12:45/+13:45 ~ Pacific/Tongatapu +13:00/+13:00
Pacific/Chatham +12:45/+13:45 ~ Etc/GMT-13 +13:00/+13:00
Pacific/Yap +10:00/+10:00 ~ Australia/Yancowinna +09:30/+10:30
Pacific/Yap +10:00/+10:00 ~ Australia/Adelaide +09:30/+10:30
Pacific/Yap +10:00/+10:00 ~ Australia/Broken_Hill +09:30/+10:30
Pacific/Yap +10:00/+10:00 ~ Australia/South +09:30/+10:30
Pacific/Port_Moresby +10:00/+10:00 ~ Australia/Yancowinna +09:30/+10:30
Pacific/Port_Moresby +10:00/+10:00 ~ Australia/Adelaide +09:30/+10:30
Pacific/Port_Moresby +10:00/+10:00 ~ Australia/Broken_Hill +09:30/+10:30
Pacific/Port_Moresby +10:00/+10:00 ~ Australia/South +09:30/+10:30
Australia/Yancowinna +09:30/+10:30 ~ Pacific/Chuuk +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Australia/Queensland +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Pacific/Guam +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Pacific/Truk +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Asia/Vladivostok +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Pacific/Saipan +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Antarctica/DumontDUrville +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Australia/Brisbane +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Etc/GMT-10 +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Asia/Ust-Nera +10:00/+10:00
Australia/Yancowinna +09:30/+10:30 ~ Australia/Lindeman +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Pacific/Chuuk +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Australia/Queensland +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Pacific/Guam +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Pacific/Truk +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Asia/Vladivostok +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Pacific/Saipan +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Antarctica/DumontDUrville +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Australia/Brisbane +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Etc/GMT-10 +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Asia/Ust-Nera +10:00/+10:00
Australia/Adelaide +09:30/+10:30 ~ Australia/Lindeman +10:00/+10:00
Pacific/Chuuk +10:00/+10:00 ~ Australia/Broken_Hill +09:30/+10:30
Pacific/Chuuk +10:00/+10:00 ~ Australia/South +09:30/+10:30
Australia/Queensland +10:00/+10:00 ~ Australia/Broken_Hill +09:30/+10:30
Australia/Queensland +10:00/+10:00 ~ Australia/South +09:30/+10:30
Australia/Broken_Hill +09:30/+10:30 ~ Pacific/Guam +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Pacific/Truk +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Asia/Vladivostok +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Pacific/Saipan +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Antarctica/DumontDUrville +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Australia/Brisbane +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Etc/GMT-10 +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Asia/Ust-Nera +10:00/+10:00
Australia/Broken_Hill +09:30/+10:30 ~ Australia/Lindeman +10:00/+10:00
Pacific/Guam +10:00/+10:00 ~ Australia/South +09:30/+10:30
Pacific/Truk +10:00/+10:00 ~ Australia/South +09:30/+10:30
Asia/Vladivostok +10:00/+10:00 ~ Australia/South +09:30/+10:30
Pacific/Saipan +10:00/+10:00 ~ Australia/South +09:30/+10:30
Antarctica/DumontDUrville +10:00/+10:00 ~ Australia/South +09:30/+10:30
Australia/South +09:30/+10:30 ~ Australia/Brisbane +10:00/+10:00
Australia/South +09:30/+10:30 ~ Etc/GMT-10 +10:00/+10:00
Australia/South +09:30/+10:30 ~ Asia/Ust-Nera +10:00/+10:00
Australia/South +09:30/+10:30 ~ Australia/Lindeman +10:00/+10:00
Etc/GMT-1 +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
Africa/Tunis +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
Africa/Malabo +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
America/Godthab -02:00/-03:00 ~ America/St_Johns -02:30/-02:30
America/Godthab -02:00/-03:00 ~ Canada/Newfoundland -02:30/-02:30
Africa/Lagos +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
Africa/Algiers +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
Africa/Ndjamena +01:00/+01:00 ~ Antarctica/Troll +02:00/Z
Antarctica/Troll +02:00/Z ~ Africa/Libreville +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/El_Aaiun +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Douala +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Brazzaville +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Porto-Novo +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Casablanca +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Luanda +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Kinshasa +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Bangui +01:00/+01:00
Antarctica/Troll +02:00/Z ~ Africa/Niamey +01:00/+01:00
America/Asuncion -04:00/-03:00 ~ SystemV/AST4ADT -03:00/-04:00
Chile/Continental -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
Chile/Continental -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Argentina/Catamarca -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Argentina/Catamarca -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
Canada/Atlantic -03:00/-04:00 ~ America/Asuncion -04:00/-03:00
America/Argentina/Cordoba -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Argentina/Cordoba -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Araguaina -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Araguaina -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Argentina/Salta -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Argentina/Salta -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
Etc/GMT+3 -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
Etc/GMT+3 -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Montevideo -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Montevideo -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
Brazil/East -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
Brazil/East -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Argentina/Mendoza -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Argentina/Mendoza -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Argentina/Rio_Gallegos -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Argentina/Rio_Gallegos -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Catamarca -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Catamarca -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Cordoba -03:00/-03:00 ~ America/St_Johns -02:30/-03:30
America/Cordoba -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/St_Johns -02:30/-03:30 ~ America/Sao_Paulo -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/Jujuy -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Cayenne -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Recife -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Buenos_Aires -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Paramaribo -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Mendoza -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Santarem -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Asuncion -04:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Maceio -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ Atlantic/Stanley -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ Antarctica/Rothera -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/San_Luis -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Santiago -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/Ushuaia -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ Antarctica/Palmer -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Punta_Arenas -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Fortaleza -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/La_Rioja -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Belem -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Jujuy -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Bahia -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/San_Juan -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/ComodRivadavia -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/Tucuman -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Rosario -03:00/-03:00
America/St_Johns -02:30/-03:30 ~ America/Argentina/Buenos_Aires -03:00/-03:00
America/Sao_Paulo -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Argentina/Jujuy -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Cayenne -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Recife -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Buenos_Aires -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Paramaribo -03:00/-03:00 ~ Canada/Newfoundland -02:30/-03:30
America/Moncton -03:00/-04:00 ~ America/Asuncion -04:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Mendoza -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Santarem -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Asuncion -04:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Maceio -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ Atlantic/Stanley -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ Antarctica/Rothera -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/San_Luis -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Santiago -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/Ushuaia -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ Antarctica/Palmer -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Punta_Arenas -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Fortaleza -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/La_Rioja -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Belem -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Jujuy -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Bahia -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/San_Juan -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/ComodRivadavia -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/Tucuman -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Rosario -03:00/-03:00
Canada/Newfoundland -02:30/-03:30 ~ America/Argentina/Buenos_Aires -03:00/-03:00
America/Asuncion -04:00/-03:00 ~ Atlantic/Bermuda -03:00/-04:00
America/Asuncion -04:00/-03:00 ~ America/Halifax -03:00/-04:00
America/Asuncion -04:00/-03:00 ~ America/Glace_Bay -03:00/-04:00
America/Asuncion -04:00/-03:00 ~ America/Thule -03:00/-04:00
America/Asuncion -04:00/-03:00 ~ America/Goose_Bay -03:00/-04:00
America/Atka -09:00/-10:00 ~ Pacific/Marquesas -09:30/-09:30
Pacific/Marquesas -09:30/-09:30 ~ America/Adak -09:00/-10:00
Pacific/Marquesas -09:30/-09:30 ~ US/Aleutian -09:00/-10:00
To sort ZoneId objects (time zones), you must specify a moment for which you want the offset (ZoneOffset) in effect in each time zone.
Instant instant = Instant.now();
record OffsetForZone( ZoneId zoneId , ZoneOffset offset ) { }
List < OffsetForZone > results =
ZoneId
.getAvailableZoneIds()
.stream()
.map(
( String zone ) -> new OffsetForZone( ZoneId.of( zone ) , ZoneId.of( zone ).getRules().getOffset( instant ) )
)
.sorted(
Comparator
.comparing( OffsetForZone :: offset ).reversed()
.thenComparing( ( OffsetForZone o ) -> o.zoneId.getId() )
)
.toList();
Zones sorted by offset in effect at 2021-09-08T08:51:02.939266Z is: [OffsetForZone[zoneId=Etc/GMT+12, offset=-12:00], OffsetForZone[zoneId=Etc/GMT+11, offset=-11:00], OffsetForZone[zoneId=Pacific/Midway, offset=-11:00], OffsetForZone[zoneId=Pacific/Niue, offset=-11:00], …
An offset-from-UTC is merely a number of hours-minutes-seconds, nothing more.
A time zone, in contrast, is much more. A time zone is a history of the past, present, and future changes to the offset used by the people of a particular region as decided by their politicians. So a time zone may have many offsets, only one of which is in effect at any moment.
So it makes no sense to order time zones by offset, unless you specify a particular moment. And even then, many time zones may coincidentally share the same offset at any particular moment.
You asked:
One timezone could be -2:00 related to UTC while another one would be +2:00 for example. Why not consider those as -2:00 < +2:00 and so on?
Because those facts could be true for one moment but not another moment. Those zones may use a different offset on a different date and time.
Here is some code to sort time zones by their offset in use at a particular moment. We will capture the current moment, as seen in UTC. For that we use the Instant class.
Instant instant = Instant.now() ;
Get a set of all the time zone identifiers.
Set < String > zones = ZoneId.getAvailableZoneIds();
For each of those zones, we need to determine the current offset. We need to store that info in objects, collected for sorting. In Java 16+, we can use a record to briefly write that class.
record OffsetForZone( ZoneId zoneId , ZoneOffset offset ) { }
Loop all the zone ids, getting the ZoneId for each. With that ZoneId, get the rules for than zone. Ask the rules for offset in effect at our specific moment. Record each ZoneId and is ZoneOffset for that moment in a list.
for ( String zone : zones )
{
ZoneId zoneId = ZoneId.of( zone );
ZoneRules rules = zoneId.getRules();
ZoneOffset offset = rules.getOffset( instant );
OffsetForZone offsetForZone = new OffsetForZone( zoneId , offset );
results.add( offsetForZone );
}
Being simply a number of hours-minutes-seconds, the ZoneOffset class implements Comparable. This means we can sort on ZoneOffset, unlike ZoneId.
We want to sort first by the offset. Secondarily, for those zones sharing the same offset in effect at that moment, we want to sort alphabetically by the zone ID.
The Comparator class makes such sorting quite easy, along with the List#sort method.
results.sort(
Comparator
.comparing( OffsetForZone :: offset )
.thenComparing( ( OffsetForZone o ) -> o.zoneId.getId() )
);
If desired, add a .reversed call to sort in opposite direction.
results.sort(
Comparator
.comparing( OffsetForZone :: offset ).reversed()
.thenComparing( ( OffsetForZone o ) -> o.zoneId.getId() )
);
Usually best to return an unmodifiable list.
results = List.copyOf( results ) ;
Dump to console.
System.out.println( "Zones sorted by offset in effect at " + instant + " is: " + results );
When run you will see something like the following. (Abbreviated to fit text limits of Stack Overflow.)
Zones sorted by offset in effect at 2021-09-08T06:40:09.461149Z is: [OffsetForZone[zoneId=Etc/GMT-14, offset=+14:00], OffsetForZone[zoneId=Pacific/Kiritimati, offset=+14:00], OffsetForZone[zoneId=Etc/GMT-13, offset=+13:00], OffsetForZone[zoneId=Pacific/Apia, offset=+13:00], OffsetForZone[zoneId=Pacific/Enderbury, offset=+13:00], OffsetForZone[zoneId=Pacific/Fakaofo, offset=+13:00], OffsetForZone[zoneId=Pacific/Tongatapu, offset=+13:00], OffsetForZone[zoneId=NZ-CHAT, offset=+12:45], OffsetForZone[zoneId=Pacific/Chatham, offset=+12:45], OffsetForZone[zoneId=Antarctica/McMurdo, offset=+12:00], OffsetForZone[zoneId=Antarctica/South_Pole, offset=+12:00], OffsetForZone[zoneId=Asia/Anadyr, offset=+12:00], OffsetForZone[zoneId=Asia/Kamchatka, offset=+12:00], OffsetForZone[zoneId=Etc/GMT-12, offset=+12:00], OffsetForZone[zoneId=Kwajalein, offset=+12:00], OffsetForZone[zoneId=NZ, offset=+12:00], OffsetForZone[zoneId=Pacific/Auckland, offset=+12:00], OffsetForZone[zoneId=Pacific/Fiji, offset=+12:00], OffsetForZone[zoneId=Pacific/Funafuti, offset=+12:00], OffsetForZone[zoneId=Pacific/Kwajalein, offset=+12:00], OffsetForZone[zoneId=Pacific/Majuro, offset=+12:00], OffsetForZone[zoneId=Pacific/Nauru, offset=+12:00], OffsetForZone[zoneId=Pacific/Tarawa, offset=+12:00], OffsetForZone[zoneId=Pacific/Wake, offset=+12:00], OffsetForZone[zoneId=Pacific/Wallis, offset=+12:00], OffsetForZone[zoneId=Antarctica/Casey, offset=+11:00], OffsetForZone[zoneId=Asia/Magadan, offset=+11:00], OffsetForZone[zoneId=Asia/Sakhalin, offset=+11:00], OffsetForZone[zoneId=Asia/Srednekolymsk, offset=+11:00], OffsetForZone[zoneId=Etc/GMT-11, offset=+11:00], OffsetForZone[zoneId=Pacific/Bougainville, offset=+11:00], OffsetForZone[zoneId=Pacific/Efate, offset=+11:00], OffsetForZone[zoneId=Pacific/Guadalcanal, offset=+11:00], OffsetForZone[zoneId=Pacific/Kosrae, offset=+11:00], OffsetForZone[zoneId=Pacific/Norfolk, offset=+11:00], OffsetForZone[zoneId=Pacific/Noumea, offset=+11:00], OffsetForZone[zoneId=Pacific/Pohnpei, offset=+11:00], OffsetForZone[zoneId=Pacific/Ponape, offset=+11:00], OffsetForZone[zoneId=Australia/LHI, offset=+10:30], OffsetForZone[zoneId=Australia/Lord_Howe, offset=+10:30], OffsetForZone[zoneId=Antarctica/DumontDUrville, offset=+10:00], OffsetForZone[zoneId=Antarctica/Macquarie, offset=+10:00], OffsetForZone[zoneId=Asia/Ust-Nera, offset=+10:00], OffsetForZone[zoneId=Asia/Vladivostok, offset=+10:00], OffsetForZone[zoneId=Australia/ACT, offset=+10:00], OffsetForZone[zoneId=Australia/Brisbane, offset=+10:00], OffsetForZone[zoneId=Australia/Canberra, offset=+10:00], OffsetForZone[zoneId=Australia/Currie, offset=+10:00], OffsetForZone[zoneId=Australia/Hobart, offset=+10:00], OffsetForZone[zoneId=Australia/Lindeman, offset=+10:00], OffsetForZone[zoneId=Australia/Melbourne, offset=+10:00], OffsetForZone[zoneId=Australia/NSW, offset=+10:00], OffsetForZone[zoneId=Australia/Queensland, offset=+10:00], OffsetForZone[zoneId=Australia/Sydney, offset=+10:00], OffsetForZone[zoneId=Australia/Tasmania, offset=+10:00], OffsetForZone[zoneId=Australia/Victoria, offset=+10:00], OffsetForZone[zoneId=Etc/GMT-10, offset=+10:00], OffsetForZone[zoneId=Pacific/Chuuk, offset=+10:00], OffsetForZone[zoneId=Pacific/Guam, offset=+10:00], OffsetForZone[zoneId=Pacific/Port_Moresby, offset=+10:00], OffsetForZone[zoneId=Pacific/Saipan, offset=+10:00], OffsetForZone[zoneId=Pacific/Truk, offset=+10:00], OffsetForZone[zoneId=Pacific/Yap, offset=+10:00], OffsetForZone[zoneId=Australia/Adelaide, offset=+09:30], OffsetForZone[zoneId=Australia/Broken_Hill, offset=+09:30], OffsetForZone[zoneId=Australia/Darwin, offset=+09:30], OffsetForZone[zoneId=Australia/North, offset=+09:30], OffsetForZone[zoneId=Australia/South, offset=+09:30], OffsetForZone[zoneId=Australia/Yancowinna, offset=+09:30], OffsetForZone[zoneId=Asia/Chita, offset=+09:00], OffsetForZone[zoneId=Asia/Dili, offset=+09:00], OffsetForZone[zoneId=Asia/Jayapura, offset=+09:00], OffsetForZone[zoneId=Asia/Khandyga, offset=+09:00], OffsetForZone[zoneId=Asia/Pyongyang, offset=+09:00], OffsetForZone[zoneId=Asia/Seoul, offset=+09:00], OffsetForZone[zoneId=Asia/Tokyo, offset=+09:00], OffsetForZone[zoneId=Asia/Yakutsk, offset=+09:00], OffsetForZone[zoneId=Etc/GMT-9, offset=+09:00], OffsetForZone[zoneId=Japan, offset=+09:00], OffsetForZone[zoneId=Pacific/Palau, offset=+09:00], OffsetForZone[zoneId=ROK, offset=+09:00], OffsetForZone[zoneId=Australia/Eucla, offset=+08:45], OffsetForZone[zoneId=Asia/Brunei, offset=+08:00], OffsetForZone[zoneId=Asia/Choibalsan, offset=+08:00], OffsetForZone[zoneId=Asia/Chongqing, offset=+08:00], OffsetForZone[zoneId=Asia/Chungking, offset=+08:00], OffsetForZone[zoneId=Asia/Harbin, offset=+08:00], OffsetForZone[zoneId=Asia/Hong_Kong, offset=+08:00], OffsetForZone[zoneId=Asia/Irkutsk, offset=+08:00], OffsetForZone[zoneId=Asia/Kuala_Lumpur, offset=+08:00], OffsetForZone[zoneId=Asia/Kuching, offset=+08:00], OffsetForZone[zoneId=Asia/Macao, offset=+08:00], OffsetForZone[zoneId=Asia/Macau, offset=+08:00], OffsetForZone[zoneId=Asia/Makassar, offset=+08:00], OffsetForZone[zoneId=Asia/Manila, offset=+08:00], OffsetForZone[zoneId=Asia/Shanghai, offset=+08:00], OffsetForZone[zoneId=Asia/Singapore, offset=+08:00], OffsetForZone[zoneId=Asia/Taipei, offset=+08:00], OffsetForZone[zoneId=Asia/Ujung_Pandang, offset=+08:00], OffsetForZone[zoneId=Asia/Ulaanbaatar, offset=+08:00], OffsetForZone[zoneId=Asia/Ulan_Bator, offset=+08:00], OffsetForZone[zoneId=Australia/Perth, offset=+08:00], OffsetForZone[zoneId=Australia/West, offset=+08:00], OffsetForZone[zoneId=Etc/GMT-8, offset=+08:00], OffsetForZone[zoneId=Hongkong, offset=+08:00], OffsetForZone[zoneId=PRC, offset=+08:00], OffsetForZone[zoneId=Singapore, offset=+08:00], OffsetForZone[zoneId=Antarctica/Davis, offset=+07:00], OffsetForZone[zoneId=Asia/Bangkok, offset=+07:00], OffsetForZone[zoneId=Asia/Barnaul, offset=+07:00], OffsetForZone[zoneId=Asia/Ho_Chi_Minh, offset=+07:00], OffsetForZone[zoneId=Asia/Hovd, offset=+07:00], OffsetForZone[zoneId=Asia/Jakarta, offset=+07:00], OffsetForZone[zoneId=Asia/Krasnoyarsk, offset=+07:00], OffsetForZone[zoneId=Asia/Novokuznetsk, offset=+07:00], OffsetForZone[zoneId=Asia/Novosibirsk, offset=+07:00], OffsetForZone[zoneId=Asia/Phnom_Penh, offset=+07:00], OffsetForZone[zoneId=Asia/Pontianak, offset=+07:00], OffsetForZone[zoneId=Asia/Saigon, offset=+07:00], OffsetForZone[zoneId=Asia/Tomsk, offset=+07:00], OffsetForZone[zoneId=Asia/Vientiane, offset=+07:00], OffsetForZone[zoneId=Etc/GMT-7, offset=+07:00], OffsetForZone[zoneId=Indian/Christmas, offset=+07:00], OffsetForZone[zoneId=Asia/Rangoon, offset=+06:30], OffsetForZone[zoneId=Asia/Yangon, offset=+06:30], OffsetForZone[zoneId=Indian/Cocos, offset=+06:30], OffsetForZone[zoneId=Antarctica/Vostok, offset=+06:00], OffsetForZone[zoneId=Asia/Almaty, offset=+06:00], OffsetForZone[zoneId=Asia/Bishkek, offset=+06:00], OffsetForZone[zoneId=Asia/Dacca, offset=+06:00], OffsetForZone[zoneId=Asia/Dhaka, offset=+06:00], OffsetForZone[zoneId=Asia/Kashgar, offset=+06:00], OffsetForZone[zoneId=Asia/Omsk, offset=+06:00], OffsetForZone[zoneId=Asia/Qostanay, offset=+06:00], OffsetForZone[zoneId=Asia/Thimbu, offset=+06:00], OffsetForZone[zoneId=Asia/Thimphu, offset=+06:00], OffsetForZone[zoneId=Asia/Urumqi, offset=+06:00], OffsetForZone[zoneId=Etc/GMT-6, offset=+06:00], OffsetForZone[zoneId=Indian/Chagos, offset=+06:00], OffsetForZone[zoneId=Asia/Kathmandu, offset=+05:45], OffsetForZone[zoneId=Asia/Katmandu, offset=+05:45], OffsetForZone[zoneId=Asia/Calcutta, offset=+05:30], OffsetForZone[zoneId=Asia/Colombo, offset=+05:30], OffsetForZone[zoneId=Asia/Kolkata, offset=+05:30], OffsetForZone[zoneId=Antarctica/Mawson, offset=+05:00], OffsetForZone[zoneId=Asia/Aqtau, offset=+05:00], OffsetForZone[zoneId=Asia/Aqtobe, offset=+05:00], OffsetForZone[zoneId=Asia/Ashgabat, offset=+05:00], OffsetForZone[zoneId=Asia/Ashkhabad, offset=+05:00], OffsetForZone[zoneId=Asia/Atyrau, offset=+05:00], OffsetForZone[zoneId=Asia/Dushanbe, offset=+05:00], OffsetForZone[zoneId=Asia/Karachi, offset=+05:00], OffsetForZone[zoneId=Asia/Oral, offset=+05:00], OffsetForZone[zoneId=Asia/Qyzylorda, offset=+05:00], OffsetForZone[zoneId=Asia/Samarkand, offset=+05:00], OffsetForZone[zoneId=Asia/Tashkent, offset=+05:00], OffsetForZone[zoneId=Asia/Yekaterinburg, offset=+05:00], OffsetForZone[zoneId=Etc/GMT-5, offset=+05:00], OffsetForZone[zoneId=Indian/Kerguelen, offset=+05:00], OffsetForZone[zoneId=Indian/Maldives, offset=+05:00], OffsetForZone[zoneId=Asia/Kabul, offset=+04:30], OffsetForZone[zoneId=Asia/Tehran, offset=+04:30], OffsetForZone[zoneId=Iran, offset=+04:30], OffsetForZone[zoneId=Asia/Baku, offset=+04:00], OffsetForZone[zoneId=Asia/Dubai, offset=+04:00], OffsetForZone[zoneId=Asia/Muscat, offset=+04:00], OffsetForZone[zoneId=Asia/Tbilisi, offset=+04:00], OffsetForZone[zoneId=Asia/Yerevan, offset=+04:00], OffsetForZone[zoneId=Etc/GMT-4, offset=+04:00], OffsetForZone[zoneId=Europe/Astrakhan, offset=+04:00], OffsetForZone[zoneId=Europe/Samara, offset=+04:00], OffsetForZone[zoneId=Europe/Saratov, offset=+04:00], OffsetForZone[zoneId=Europe/Ulyanovsk, offset=+04:00], OffsetForZone[zoneId=Indian/Mahe, offset=+04:00], OffsetForZone[zoneId=Indian/Mauritius, offset=+04:00], OffsetForZone[zoneId=Indian/Reunion, offset=+04:00], OffsetForZone[zoneId=Africa/Addis_Ababa, offset=+03:00], OffsetForZone[zoneId=Africa/Asmara, offset=+03:00], OffsetForZone[zoneId=Africa/Asmera, offset=+03:00], OffsetForZone[zoneId=Africa/Dar_es_Salaam, offset=+03:00], OffsetForZone[zoneId=Africa/Djibouti, offset=+03:00], OffsetForZone[zoneId=Africa/Kampala, offset=+03:00], OffsetForZone[zoneId=Africa/Mogadishu, offset=+03:00], OffsetForZone[zoneId=Africa/Nairobi, offset=+03:00], OffsetForZone[zoneId=Antarctica/Syowa, offset=+03:00], OffsetForZone[zoneId=Asia/Aden, offset=+03:00], OffsetForZone[zoneId=Asia/Amman, offset=+03:00], OffsetForZone[zoneId=Asia/Baghdad, offset=+03:00], OffsetForZone[zoneId=Asia/Bahrain, offset=+03:00], OffsetForZone[zoneId=Asia/Beirut, offset=+03:00], OffsetForZone[zoneId=Asia/Damascus, offset=+03:00], OffsetForZone[zoneId=Asia/Famagusta, offset=+03:00], OffsetForZone[zoneId=Asia/Gaza, offset=+03:00], OffsetForZone[zoneId=Asia/Hebron, offset=+03:00], OffsetForZone[zoneId=Asia/Istanbul, offset=+03:00], OffsetForZone[zoneId=Asia/Jerusalem, offset=+03:00], OffsetForZone[zoneId=Asia/Kuwait, offset=+03:00], OffsetForZone[zoneId=Asia/Nicosia, offset=+03:00], OffsetForZone[zoneId=Asia/Qatar, offset=+03:00], OffsetForZone[zoneId=Asia/Riyadh, offset=+03:00], OffsetForZone[zoneId=Asia/Tel_Aviv, offset=+03:00], OffsetForZone[zoneId=EET, offset=+03:00], OffsetForZone[zoneId=Etc/GMT-3, offset=+03:00], OffsetForZone[zoneId=Europe/Athens, offset=+03:00], OffsetForZone[zoneId=Europe/Bucharest, offset=+03:00], OffsetForZone[zoneId=Europe/Chisinau, offset=+03:00], OffsetForZone[zoneId=Europe/Helsinki, offset=+03:00], OffsetForZone[zoneId=Europe/Istanbul, offset=+03:00], OffsetForZone[zoneId=Europe/Kiev, offset=+03:00], OffsetForZone[zoneId=Europe/Kirov, offset=+03:00], OffsetForZone[zoneId=Europe/Mariehamn, offset=+03:00], OffsetForZone[zoneId=Europe/Minsk, offset=+03:00], OffsetForZone[zoneId=Europe/Moscow, offset=+03:00], OffsetForZone[zoneId=Europe/Nicosia, offset=+03:00], OffsetForZone[zoneId=Europe/Riga, offset=+03:00], OffsetForZone[zoneId=Europe/Simferopol, offset=+03:00], OffsetForZone[zoneId=Europe/Sofia, offset=+03:00], OffsetForZone[zoneId=Europe/Tallinn, offset=+03:00], OffsetForZone[zoneId=Europe/Tiraspol, offset=+03:00], OffsetForZone[zoneId=Europe/Uzhgorod, offset=+03:00], OffsetForZone[zoneId=Europe/Vilnius, offset=+03:00], OffsetForZone[zoneId=Europe/Volgograd, offset=+03:00], OffsetForZone[zoneId=Europe/Zaporozhye, offset=+03:00], OffsetForZone[zoneId=Indian/Antananarivo, offset=+03:00], OffsetForZone[zoneId=Indian/Comoro, offset=+03:00], OffsetForZone[zoneId=Indian/Mayotte, offset=+03:00], OffsetForZone[zoneId=Israel, offset=+03:00], OffsetForZone[zoneId=Turkey, offset=+03:00], OffsetForZone[zoneId=W-SU, offset=+03:00], OffsetForZone[zoneId=Africa/Blantyre, offset=+02:00], OffsetForZone[zoneId=Africa/Bujumbura, offset=+02:00], OffsetForZone[zoneId=Africa/Cairo, offset=+02:00], OffsetForZone[zoneId=Africa/Ceuta, offset=+02:00], OffsetForZone[zoneId=Africa/Gaborone, offset=+02:00], OffsetForZone[zoneId=Africa/Harare, offset=+02:00], OffsetForZone[zoneId=Africa/Johannesburg, offset=+02:00], OffsetForZone[zoneId=Africa/Juba, offset=+02:00], OffsetForZone[zoneId=Africa/Khartoum, offset=+02:00], OffsetForZone[zoneId=Africa/Kigali, offset=+02:00], OffsetForZone[zoneId=Africa/Lubumbashi, offset=+02:00], OffsetForZone[zoneId=Africa/Lusaka, offset=+02:00], OffsetForZone[zoneId=Africa/Maputo, offset=+02:00], OffsetForZone[zoneId=Africa/Maseru, offset=+02:00], OffsetForZone[zoneId=Africa/Mbabane, offset=+02:00], OffsetForZone[zoneId=Africa/Tripoli, offset=+02:00], OffsetForZone[zoneId=Africa/Windhoek, offset=+02:00], OffsetForZone[zoneId=Antarctica/Troll, offset=+02:00], OffsetForZone[zoneId=Arctic/Longyearbyen, offset=+02:00], OffsetForZone[zoneId=Atlantic/Jan_Mayen, offset=+02:00], OffsetForZone[zoneId=CET, offset=+02:00], OffsetForZone[zoneId=Egypt, offset=+02:00], OffsetForZone[zoneId=Etc/GMT-2, offset=+02:00], OffsetForZone[zoneId=Europe/Amsterdam, offset=+02:00], OffsetForZone[zoneId=Europe/Andorra, offset=+02:00], OffsetForZone[zoneId=Europe/Belgrade, offset=+02:00], OffsetForZone[zoneId=Europe/Berlin, offset=+02:00], OffsetForZone[zoneId=Europe/Bratislava, offset=+02:00], OffsetForZone[zoneId=Europe/Brussels, offset=+02:00], OffsetForZone[zoneId=Europe/Budapest, offset=+02:00], OffsetForZone[zoneId=Europe/Busingen, offset=+02:00], OffsetForZone[zoneId=Europe/Copenhagen, offset=+02:00], OffsetForZone[zoneId=Europe/Gibraltar, offset=+02:00], OffsetForZone[zoneId=Europe/Kaliningrad, offset=+02:00], OffsetForZone[zoneId=Europe/Ljubljana, offset=+02:00], OffsetForZone[zoneId=Europe/Luxembourg, offset=+02:00], OffsetForZone[zoneId=Europe/Madrid, offset=+02:00], OffsetForZone[zoneId=Europe/Malta, offset=+02:00], OffsetForZone[zoneId=Europe/Monaco, offset=+02:00], OffsetForZone[zoneId=Europe/Oslo, offset=+02:00], OffsetForZone[zoneId=Europe/Paris, offset=+02:00], OffsetForZone[zoneId=Europe/Podgorica, offset=+02:00], OffsetForZone[zoneId=Europe/Prague, offset=+02:00], OffsetForZone[zoneId=Europe/Rome, offset=+02:00], OffsetForZone[zoneId=Europe/San_Marino, offset=+02:00], OffsetForZone[zoneId=Europe/Sarajevo, offset=+02:00], OffsetForZone[zoneId=Europe/Skopje, offset=+02:00], OffsetForZone[zoneId=Europe/Stockholm, offset=+02:00], OffsetForZone[zoneId=Europe/Tirane, offset=+02:00], OffsetForZone[zoneId=Europe/Vaduz, offset=+02:00], OffsetForZone[zoneId=Europe/Vatican, offset=+02:00], OffsetForZone[zoneId=Europe/Vienna, offset=+02:00], OffsetForZone[zoneId=Europe/Warsaw, offset=+02:00], OffsetForZone[zoneId=Europe/Zagreb, offset=+02:00], OffsetForZone[zoneId=Europe/Zurich, offset=+02:00], OffsetForZone[zoneId=Libya, offset=+02:00], OffsetForZone[zoneId=MET, offset=+02:00], OffsetForZone[zoneId=Poland, offset=+02:00], OffsetForZone[zoneId=Africa/Algiers, offset=+01:00], OffsetForZone[zoneId=Africa/Bangui, offset=+01:00], OffsetForZone[zoneId=Africa/Brazzaville, offset=+01:00], OffsetForZone[zoneId=Africa/Casablanca, offset=+01:00], OffsetForZone[zoneId=Africa/Douala, offset=+01:00], OffsetForZone[zoneId=Africa/El_Aaiun, offset=+01:00], OffsetForZone[zoneId=Africa/Kinshasa, offset=+01:00], OffsetForZone[zoneId=Africa/Lagos, offset=+01:00], OffsetForZone[zoneId=Africa/Libreville, offset=+01:00], OffsetForZone[zoneId=Africa/Luanda, offset=+01:00], OffsetForZone[zoneId=Africa/Malabo, offset=+01:00], OffsetForZone[zoneId=Africa/Ndjamena, offset=+01:00], OffsetForZone[zoneId=Africa/Niamey, offset=+01:00], OffsetForZone[zoneId=Africa/Porto-Novo, offset=+01:00], OffsetForZone[zoneId=Africa/Tunis, offset=+01:00], OffsetForZone[zoneId=Atlantic/Canary, offset=+01:00], OffsetForZone[zoneId=Atlantic/Faeroe, offset=+01:00], OffsetForZone[zoneId=Atlantic/Faroe, offset=+01:00], OffsetForZone[zoneId=Atlantic/Madeira, offset=+01:00], OffsetForZone[zoneId=Eire, offset=+01:00], OffsetForZone[zoneId=Etc/GMT-1, offset=+01:00], OffsetForZone[zoneId=Europe/Belfast, offset=+01:00], OffsetForZone[zoneId=Europe/Dublin, offset=+01:00], OffsetForZone[zoneId=Europe/Guernsey, offset=+01:00], OffsetForZone[zoneId=Europe/Isle_of_Man, offset=+01:00], OffsetForZone[zoneId=Europe/Jersey, offset=+01:00], OffsetForZone[zoneId=Europe/Lisbon, offset=+01:00], OffsetForZone[zoneId=Europe/London, offset=+01:00], OffsetForZone[zoneId=GB, offset=+01:00], OffsetForZone[zoneId=GB-Eire, offset=+01:00], OffsetForZone[zoneId=Portugal, offset=+01:00], OffsetForZone[zoneId=WET, offset=+01:00], OffsetForZone[zoneId=Africa/Abidjan, offset=Z], OffsetForZone[zoneId=Africa/Accra, offset=Z], OffsetForZone[zoneId=Africa/Bamako, offset=Z], OffsetForZone[zoneId=Africa/Banjul, offset=Z], OffsetForZone[zoneId=Africa/Bissau, offset=Z], OffsetForZone[zoneId=Africa/Conakry, offset=Z], OffsetForZone[zoneId=Africa/Dakar, offset=Z], OffsetForZone[zoneId=Africa/Freetown, offset=Z], OffsetForZone[zoneId=Africa/Lome, offset=Z], OffsetForZone[zoneId=Africa/Monrovia, offset=Z], OffsetForZone[zoneId=Africa/Nouakchott, offset=Z], OffsetForZone[zoneId=Africa/Ouagadougou, offset=Z], OffsetForZone[zoneId=Africa/Sao_Tome, offset=Z], OffsetForZone[zoneId=Africa/Timbuktu, offset=Z], OffsetForZone[zoneId=America/Danmarkshavn, offset=Z], OffsetForZone[zoneId=America/Scoresbysund, offset=Z], OffsetForZone[zoneId=Atlantic/Azores, offset=Z], OffsetForZone[zoneId=Atlantic/Reykjavik, offset=Z], OffsetForZone[zoneId=Atlantic/St_Helena, offset=Z], OffsetForZone[zoneId=Etc/GMT, offset=Z], OffsetForZone[zoneId=Etc/GMT+0, offset=Z], OffsetForZone[zoneId=Etc/GMT-0, offset=Z], OffsetForZone[zoneId=Etc/GMT0, offset=Z], OffsetForZone[zoneId=Etc/Greenwich, offset=Z], OffsetForZone[zoneId=Etc/UCT, offset=Z], OffsetForZone[zoneId=Etc/UTC, offset=Z], OffsetForZone[zoneId=Etc/Universal, offset=Z], OffsetForZone[zoneId=Etc/Zulu, offset=Z], OffsetForZone[zoneId=GMT, offset=Z], OffsetForZone[zoneId=GMT0, offset=Z], OffsetForZone[zoneId=Greenwich, offset=Z], OffsetForZone[zoneId=Iceland, offset=Z], OffsetForZone[zoneId=UCT, offset=Z], OffsetForZone[zoneId=UTC, offset=Z], OffsetForZone[zoneId=Universal, offset=Z], OffsetForZone[zoneId=Zulu, offset=Z], …