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?
A ZoneId is used to identify the rules used to convert between an Instant and a LocalDateTime . There are two distinct types of ID: Fixed offsets - a fully resolved offset from UTC/Greenwich, that uses the same offset for all local date-times.
A ZonedDateTime represents a date-time with a time offset and/or a time zone in the ISO-8601 calendar system. On its own, ZonedDateTime only supports specifying time offsets such as UTC or UTC+02:00 , plus the SYSTEM time zone ID.
ZonedDateTime is an immutable representation of a date-time with a time-zone. This class stores all date and time fields, to a precision of nanoseconds, and a time-zone, with a zone offset used to handle ambiguous local date-times. For example, the value "2nd October 2007 at 13:45.30.
ZoneOffset extends ZoneId and defines the fixed offset of the current time-zone with GMT/UTC, such as +02:00. This means that this number represents fixed hours and minutes, representing the difference between the time in current time-zone and GMT/UTC: LocalDateTime now = LocalDateTime.
Java ZoneId class specifies a time zone identifier and provides a rule for converting between an Instant and a LocalDateTime. It inherits Object class and implements the Serializable interface. Let's see the declaration of java.time.ZoneId class. It is used to get the textual representation of the zone, such as 'India Time' or '+05:30'.
The Comparable interface is used to compare an object of the same class with an instance of that class, it provides ordering of data for objects of the user-defined class. The class has to implement the java.lang.Comparable interface to compare its instance, it provides the compareTo method that takes a parameter of the object of that class.
But this information can be updated without changing the Java version (using the Timezone Updater Tool ). If the timezone data is updated (but Java version stays the same) and a new zone ID is created, there would be no equivalent Enum for it, leaving the API "incomplete".
A zone map overrides to enable the short time-zone names to be used. The use of short zone IDs has been deprecated in java.util.TimeZone. This map allows the IDs to still be used via the of (String, Map) factory method.
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], …
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With