ZoneId
The TimeZone class is now legacy, supplanted years ago by the modern java.time classes defined in JSR 310. Specifically replaced by java.time.ZoneId.
Most of the currently used time zones are in the name format of Continent/Region. See a sortable list at Wikipedia.
Get a list of all the time zone names.
Set<String> zoneIds = ZoneId.getAvailableZoneIds() ;
System.out.println( "zoneIds = " + zoneIds );
See a distinct list of those prefixes.
zoneIds.stream().map( s -> s.split( "/" )[0] ).collect( Collectors.toSet()).stream().forEach( System.out::println );
As mentioned in the Answer by tbruyelle, one way to narrow the list for presentation to the user is to filter on that Continent portion. Of those, I would guess it best to focus on:
- Europe
- Africa
- Antarctica
- Atlantic
- America
- Pacific
- Indian
- Australia
…plus add Etc/UTC.
In Java code, sorted alphabetically.
List < String > zoneGroupNames = List.of(
"Africa" ,
"Antarctica" ,
"Atlantic" ,
"America" ,
"Australia" ,
"Europe" ,
"Indian" ,
"Pacific" ,
"UTC"
);
Multimap of zone group name to zone names
Build a Map of each zone group name to collection of zone id names. We need a map of the group name such as Europe to a list of the zone names such as Europe/Berlin, Europe/London, and Europe/Malta.
Map < String, List < String > > mapGroupNameToZoneNames = new TreeMap <>();
Mapping a key to a collection of values is known as a "multimap". We now have built-in multimap functionality with the Map implementations bundled with Java. Call Map::computeIfAbsent (see this Answer).
Set < String > zoneIdStrings = ZoneId.getAvailableZoneIds();
for ( String zoneIdString : zoneIdStrings )
{
String groupName = zoneIdString.split( "/" )[ 0 ];
if ( zoneGroupNames.contains( groupName ) )
{
mapGroupNameToZoneNames.computeIfAbsent( groupName , ( x -> new ArrayList <>() ) ).add( zoneIdString );
} // Else skip it.
}
System.out.println( "mapGroupNameToZoneNames = " + mapGroupNameToZoneNames );
Present to user
Present that list of groups to the user. Say the user selects item # 6 (index 5), which is currently Europe.
String groupNameChosenByUser = zoneGroupNames.get( 5 ); // Europe
List < String > zoneNamesOfGroup = mapGroupNameToZoneNames.get( groupNameChosenByUser );
Present that list of zone names for that one group. Say the user selects item # 12 (index 11), which is currently Europe/Malta.
String zoneNameChosenByUser = zoneNamesOfGroup.get( 11 ); // Malta
Make a ZoneId object from the string of that zone name.
ZoneId zoneIdChosenByUser = ZoneId.of( zoneNameChosenByUser );
zoneIdChosenByUser.toString() = Europe/Malta