As noted in your question and in my comment, ZoneRulesProvider.getAvailableZoneIds()
creates a new set of all the available time zones’ string representation (the keys of the static final ConcurrentMap<String, ZoneRulesProvider> ZONES
) each time a time zone needs to be parsed.1
Fortunately, a ZoneRulesProvider
is an abstract
class which is designed to be subclassed. The method protected abstract Set<String> provideZoneIds()
is responsible for populating ZONES
. Thus, a subclass can provide only the needed time zones if it knows ahead of time of all time zones to be used. Since the class will provide less entries than the default provider, which contains hundreds of entries, it has the potential to significantly reduce the invocation time of getAvailableZoneIds()
.
The ZoneRulesProvider API provides instructions on how to register one. Note that providers can’t be deregistered, only supplemented, so it is not a simple matter of removing the default provider and adding your own. The system property java.time.zone.DefaultZoneRulesProvider
defines the default provider. If it returns null
(via System.getProperty("..."
) then the JVM’s notorious provider is loaded. Using System.setProperty("...", "fully-qualified name of a concrete ZoneRulesProvider class")
one can supply their own provider, which is the one discussed in the 2nd paragraph.
To conclude, I suggest:
- Subclass the
abstract class ZoneRulesProvider
- Implements the
protected abstract Set<String> provideZoneIds()
with only the needed time zones. - Set the system property to this class.
I did not do it myself, but I am sure it will fail for some reason think it will work.
1 It is suggested in the comments of the question that the exact nature of the invocation might have changed between 1.8 versions.
Edit: more information found
The aforementioned default ZoneRulesProvider
is final class TzdbZoneRulesProvider
located in java.time.zone
. The regions in that class are read from the path: JAVA_HOME/lib/tzdb.dat
(in my case it’s in the JDK’s JRE). That file indeed contains many regions, here is a snippet:
TZDB 2014cJ Africa/Abidjan Africa/Accra Africa/Addis_Ababa Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau Africa/Blantyre Africa/Brazzaville Africa/Bujumbura Africa/Cairo Africa/Casablanca Africa/Ceuta Africa/Conakry Africa/Dakar Africa/Dar_es_Salaam Africa/Djibouti
Africa/Douala Africa/El_Aaiun Africa/Freetown Africa/Gaborone
Africa/Harare Africa/Johannesburg Africa/Juba Africa/Kampala Africa/Khartoum
Africa/Kigali Africa/Kinshasa Africa/Lagos Africa/Libreville Africa/Lome
Africa/Luanda Africa/Lubumbashi
Africa/Lusaka
Africa/Malabo
Africa/Maputo
Africa/Maseru Africa/Mbabane Africa/Mogadishu Africa/Monrovia Africa/Nairobi Africa/Ndjamena
Africa/Niamey Africa/Nouakchott Africa/Ouagadougou Africa/Porto-Novo Africa/Sao_Tome Africa/Timbuktu Africa/Tripoli Africa/Tunis Africa/Windhoek America/Adak America/Anchorage America/Anguilla America/Antigua America/Araguaina America/Argentina/Buenos_Aires America/Argentina/Catamarca America/Argentina/ComodRivadavia America/Argentina/Cordoba America/Argentina/Jujuy America/Argentina/La_Rioja America/Argentina/Mendoza America/Argentina/Rio_Gallegos America/Argentina/Salta America/Argentina/San_Juan America/Argentina/San_Luis America/Argentina/Tucuman America/Argentina/Ushuaia
America/Aruba America/Asuncion America/Atikokan America/Atka
America/Bahia
Then If one finds a way to create a similar file with only the needed zones and load that one instead, the performance issues will probably not surely be resolved.