If you want the zones which are currently having an offset of e.g. +02:00 hours from UTC, you could try to collect the zone names (not directly ZoneId
objects) by filtering via getAvailableZoneIds()
, getRules()
and getOffset(Instant instant)
. The latter needs an argument defining the moment in time this method is based on.
In this example it is now ⇒ Instant.now()
:
public static void main(String[] args) throws Exception {
// define the desired offset
ZoneOffset plusTwo = ZoneOffset.ofHours(2);
// collect all the zones that have this offset at the moment
List<String> zonesWithPlusTwo =
ZoneId.getAvailableZoneIds()
.stream()
// filter by those that currently have the given offset
.filter(zoneId -> ZoneId.of(zoneId)
.getRules()
.getOffset(Instant.now())
.equals(plusTwo))
.sorted()
.collect(Collectors.toList());
// print the collected zones
zonesWithPlusTwo.forEach(System.out::println);
}
Today, 25th of August 2021, the output was
Africa/Blantyre
Africa/Bujumbura
Africa/Cairo
Africa/Ceuta
Africa/Gaborone
Africa/Harare
Africa/Johannesburg
Africa/Khartoum
Africa/Kigali
Africa/Lubumbashi
Africa/Lusaka
Africa/Maputo
Africa/Maseru
Africa/Mbabane
Africa/Tripoli
Africa/Windhoek
Antarctica/Troll
Arctic/Longyearbyen
Atlantic/Jan_Mayen
CET
Egypt
Etc/GMT-2
Europe/Amsterdam
Europe/Andorra
Europe/Belgrade
Europe/Berlin
Europe/Bratislava
Europe/Brussels
Europe/Budapest
Europe/Busingen
Europe/Copenhagen
Europe/Gibraltar
Europe/Kaliningrad
Europe/Ljubljana
Europe/Luxembourg
Europe/Madrid
Europe/Malta
Europe/Monaco
Europe/Oslo
Europe/Paris
Europe/Podgorica
Europe/Prague
Europe/Rome
Europe/San_Marino
Europe/Sarajevo
Europe/Skopje
Europe/Stockholm
Europe/Tirane
Europe/Vaduz
Europe/Vatican
Europe/Vienna
Europe/Warsaw
Europe/Zagreb
Europe/Zurich
Libya
MET
Poland
EDIT:
Considering the comment by @BasilBorque, here's an example method that takes two arguments, a value for an offset and an Instant
to base the calculation on:
public static List<String> getZones(int offsetHours, Instant base) {
// create the offset
ZoneOffset offset = ZoneOffset.ofHours(offsetHours);
// collect all the zones that have this offset at the moment
return ZoneId.getAvailableZoneIds()
.stream()
// filter by those that currently have the given offset
.filter(zoneId -> ZoneId.of(zoneId)
.getRules()
.getOffset(base)
.equals(offset))
.sorted()
.collect(Collectors.toList());
}
You can create a local variable (maybe a class member) in order to pass that to the method. That would decrease the amount of calls to Instant.now()
and enables you to use Instant
s different from the moment of calling the method.