@Test public void litmus() { AndroidThreeTen.init(context); assertThat(ZoneRulesProvider.getAvailableZoneIds()).isNotEmpty(); } }
@Override protected void initializeProviders() { TzdbZoneRulesProvider provider; InputStream is = null; try { is = context.getAssets().open("org/threeten/bp/TZDB.dat"); provider = new TzdbZoneRulesProvider(is); } catch (IOException e) { throw new IllegalStateException("TZDB.dat missing from assets.", e); } finally { if (is != null) { try { is.close(); } catch (IOException ignored) { } } } ZoneRulesProvider.registerProvider(provider); } }
/** * Call on background thread to eagerly load all zones. Starts with loading * {@link ZoneId#systemDefault()} which is the one most likely to be used. */ @WorkerThread public static void cacheZones() { ZoneId.systemDefault().getRules(); for (String zoneId : ZoneRulesProvider.getAvailableZoneIds()) { ZoneRulesProvider.getRules(zoneId, true); } }
@Override public ZoneRules getRules() { // additional query for group provider when null allows for possibility // that the provider was added after the ZoneId was created return (rules != null ? rules : ZoneRulesProvider.getRules(id, false)); }
/** * Gets the rules for the zone ID. * <p> * This returns the latest available rules for the zone ID. * <p> * This method relies on time-zone data provider files that are configured. * These are loaded using a {@code ServiceLoader}. * <p> * The caching flag is designed to allow provider implementations to * prevent the rules being cached in {@code ZoneId}. * Under normal circumstances, the caching of zone rules is highly desirable * as it will provide greater performance. However, there is a use case where * the caching would not be desirable, see {@link #provideRules}. * * @param zoneId the zone ID as defined by {@code ZoneId}, not null * @param forCaching whether the rules are being queried for caching, * true if the returned rules will be cached by {@code ZoneId}, * false if they will be returned to the user without being cached in {@code ZoneId} * @return the rules, null if {@code forCaching} is true and this * is a dynamic provider that wants to prevent caching in {@code ZoneId}, * otherwise not null * @throws ZoneRulesException if rules cannot be obtained for the zone ID */ public static ZoneRules getRules(String zoneId, boolean forCaching) { Jdk8Methods.requireNonNull(zoneId, "zoneId"); return getProvider(zoneId).provideRules(zoneId, forCaching); }
/** * Gets the history of rules for the zone ID. * <p> * Time-zones are defined by governments and change frequently. * This method allows applications to find the history of changes to the * rules for a single zone ID. The map is keyed by a string, which is the * version string associated with the rules. * <p> * The exact meaning and format of the version is provider specific. * The version must follow lexicographical order, thus the returned map will * be order from the oldest known rules to the newest available rules. * The default 'TZDB' group uses version numbering consisting of the year * followed by a letter, such as '2009e' or '2012f'. * <p> * Implementations must provide a result for each valid zone ID, however * they do not have to provide a history of rules. * Thus the map will always contain one element, and will only contain more * than one element if historical rule information is available. * * @param zoneId the zone region ID as used by {@code ZoneId}, not null * @return a modifiable copy of the history of the rules for the ID, sorted * from oldest to newest, not null * @throws ZoneRulesException if history cannot be obtained for the zone ID */ public static NavigableMap<String, ZoneRules> getVersions(String zoneId) { Jdk8Methods.requireNonNull(zoneId, "zoneId"); return getProvider(zoneId).provideVersions(zoneId); }
/** * Refreshes the rules from the underlying data provider. * <p> * This method is an extension point that allows providers to refresh their * rules dynamically at a time of the applications choosing. * After calling this method, the offset stored in any {@link ZonedDateTime} * may be invalid for the zone ID. * <p> * Dynamic behavior is entirely optional and most providers, including the * default provider, do not support it. * * @return true if the rules were updated * @throws ZoneRulesException if an error occurs during the refresh */ public static boolean refresh() { boolean changed = false; for (ZoneRulesProvider provider : PROVIDERS) { changed |= provider.provideRefresh(); } return changed; }
@Override public ZoneRules getRules() { // additional query for group provider when null allows for possibility // that the provider was added after the ZoneId was created return (rules != null ? rules : ZoneRulesProvider.getRules(id, false)); }
/** * Gets the rules for the zone ID. * <p> * This returns the latest available rules for the zone ID. * <p> * This method relies on time-zone data provider files that are configured. * These are loaded using a {@code ServiceLoader}. * <p> * The caching flag is designed to allow provider implementations to * prevent the rules being cached in {@code ZoneId}. * Under normal circumstances, the caching of zone rules is highly desirable * as it will provide greater performance. However, there is a use case where * the caching would not be desirable, see {@link #provideRules}. * * @param zoneId the zone ID as defined by {@code ZoneId}, not null * @param forCaching whether the rules are being queried for caching, * true if the returned rules will be cached by {@code ZoneId}, * false if they will be returned to the user without being cached in {@code ZoneId} * @return the rules, null if {@code forCaching} is true and this * is a dynamic provider that wants to prevent caching in {@code ZoneId}, * otherwise not null * @throws ZoneRulesException if rules cannot be obtained for the zone ID */ public static ZoneRules getRules(String zoneId, boolean forCaching) { Jdk8Methods.requireNonNull(zoneId, "zoneId"); return getProvider(zoneId).provideRules(zoneId, forCaching); }
/** * Gets the history of rules for the zone ID. * <p> * Time-zones are defined by governments and change frequently. * This method allows applications to find the history of changes to the * rules for a single zone ID. The map is keyed by a string, which is the * version string associated with the rules. * <p> * The exact meaning and format of the version is provider specific. * The version must follow lexicographical order, thus the returned map will * be order from the oldest known rules to the newest available rules. * The default 'TZDB' group uses version numbering consisting of the year * followed by a letter, such as '2009e' or '2012f'. * <p> * Implementations must provide a result for each valid zone ID, however * they do not have to provide a history of rules. * Thus the map will always contain one element, and will only contain more * than one element if historical rule information is available. * * @param zoneId the zone region ID as used by {@code ZoneId}, not null * @return a modifiable copy of the history of the rules for the ID, sorted * from oldest to newest, not null * @throws ZoneRulesException if history cannot be obtained for the zone ID */ public static NavigableMap<String, ZoneRules> getVersions(String zoneId) { Jdk8Methods.requireNonNull(zoneId, "zoneId"); return getProvider(zoneId).provideVersions(zoneId); }
/** * Refreshes the rules from the underlying data provider. * <p> * This method is an extension point that allows providers to refresh their * rules dynamically at a time of the applications choosing. * After calling this method, the offset stored in any {@link ZonedDateTime} * may be invalid for the zone ID. * <p> * Dynamic behavior is entirely optional and most providers, including the * default provider, do not support it. * * @return true if the rules were updated * @throws ZoneRulesException if an error occurs during the refresh */ public static boolean refresh() { boolean changed = false; for (ZoneRulesProvider provider : PROVIDERS) { changed |= provider.provideRefresh(); } return changed; }
/** * Gets the set of available zone IDs. * <p> * This set includes the string form of all available region-based IDs. * Offset-based zone IDs are not included in the returned set. * The ID can be passed to {@link #of(String)} to create a {@code ZoneId}. * <p> * The set of zone IDs can increase over time, although in a typical application * the set of IDs is fixed. Each call to this method is thread-safe. * * @return a modifiable copy of the set of zone IDs, not null */ public static Set<String> getAvailableZoneIds() { return new HashSet<String>(ZoneRulesProvider.getAvailableZoneIds()); }
private SortedMap<String, ZoneRules> generateZones(String... zoneIds) throws IOException { SortedMap<String, ZoneRules> zones = new TreeMap<>(); for (String zoneId : zoneIds) { zones.put(zoneId, ZoneRulesProvider.getRules(zoneId, false)); } zoneWriter.writeZones(zones); return zones; }
@Override protected void initializeProviders() { ZoneRulesProvider.registerProvider(new LazyZoneRulesProvider(application)); } }
/** * Gets the set of available zone IDs. * <p> * This set includes the string form of all available region-based IDs. * Offset-based zone IDs are not included in the returned set. * The ID can be passed to {@link #of(String)} to create a {@code ZoneId}. * <p> * The set of zone IDs can increase over time, although in a typical application * the set of IDs is fixed. Each call to this method is thread-safe. * * @return a modifiable copy of the set of zone IDs, not null */ public static Set<String> getAvailableZoneIds() { return new HashSet<String>(ZoneRulesProvider.getAvailableZoneIds()); }
/** * Obtains an instance of {@code ZoneId} from an identifier. * * @param zoneId the time-zone ID, not null * @param checkAvailable whether to check if the zone ID is available * @return the zone ID, not null * @throws DateTimeException if the ID format is invalid * @throws DateTimeException if checking availability and the ID cannot be found */ static ZoneRegion ofId(String zoneId, boolean checkAvailable) { Jdk8Methods.requireNonNull(zoneId, "zoneId"); if (zoneId.length() < 2 || PATTERN.matcher(zoneId).matches() == false) { throw new DateTimeException("Invalid ID for region-based ZoneId, invalid format: " + zoneId); } ZoneRules rules = null; try { // always attempt load for better behavior after deserialization rules = ZoneRulesProvider.getRules(zoneId, true); } catch (ZoneRulesException ex) { // special case as removed from data file if (zoneId.equals("GMT0")) { rules = ZoneOffset.UTC.getRules(); } else if (checkAvailable) { throw ex; } } return new ZoneRegion(zoneId, rules); }
@Override protected void initializeProviders() { ServiceLoader<ZoneRulesProvider> loader = ServiceLoader.load(ZoneRulesProvider.class, ZoneRulesProvider.class.getClassLoader()); for (ZoneRulesProvider provider : loader) { try { ZoneRulesProvider.registerProvider(provider); } catch (ServiceConfigurationError ex) { if (!(ex.getCause() instanceof SecurityException)) { throw ex; } } } } }
@Test public void init() { LazyThreeTen.init(context); assertThat(ZoneRulesProvider.getAvailableZoneIds()).isNotEmpty(); }
/** * Obtains an instance of {@code ZoneId} from an identifier. * * @param zoneId the time-zone ID, not null * @param checkAvailable whether to check if the zone ID is available * @return the zone ID, not null * @throws DateTimeException if the ID format is invalid * @throws DateTimeException if checking availability and the ID cannot be found */ static ZoneRegion ofId(String zoneId, boolean checkAvailable) { Jdk8Methods.requireNonNull(zoneId, "zoneId"); if (zoneId.length() < 2 || PATTERN.matcher(zoneId).matches() == false) { throw new DateTimeException("Invalid ID for region-based ZoneId, invalid format: " + zoneId); } ZoneRules rules = null; try { // always attempt load for better behavior after deserialization rules = ZoneRulesProvider.getRules(zoneId, true); } catch (ZoneRulesException ex) { // special case as removed from data file if (zoneId.equals("GMT0")) { rules = ZoneOffset.UTC.getRules(); } else if (checkAvailable) { throw ex; } } return new ZoneRegion(zoneId, rules); }
@Override protected void initializeProviders() { ServiceLoader<ZoneRulesProvider> loader = ServiceLoader.load(ZoneRulesProvider.class, ZoneRulesProvider.class.getClassLoader()); for (ZoneRulesProvider provider : loader) { try { ZoneRulesProvider.registerProvider(provider); } catch (ServiceConfigurationError ex) { if (!(ex.getCause() instanceof SecurityException)) { throw ex; } } } } }