blob: ada59d6d7d553259e3725d6185863d9d6b7b0424 [file] [log] [blame]
Neil Fullerf7346ec2019-08-30 18:02:47 +01001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.timezone;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.annotation.SuppressLint;
22import android.annotation.SystemApi;
23import android.icu.util.TimeZone;
24
25import java.util.ArrayList;
26import java.util.Collections;
27import java.util.List;
28import java.util.Objects;
29
30/**
31 * Information about a country's time zones.
32 *
33 * @hide
34 */
35@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
36public final class CountryTimeZones {
37
38 /**
39 * A mapping to a time zone ID with some associated metadata.
40 *
41 * @hide
42 */
43 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
44 public static final class TimeZoneMapping {
45
46 private libcore.timezone.CountryTimeZones.TimeZoneMapping mDelegate;
47
48 TimeZoneMapping(libcore.timezone.CountryTimeZones.TimeZoneMapping delegate) {
49 this.mDelegate = Objects.requireNonNull(delegate);
50 }
51
52 /**
53 * Returns the ID for this mapping. See also {@link #getTimeZone()} which handles when the
54 * ID is unrecognized.
55 */
56 @NonNull
57 public String getTimeZoneId() {
58 return mDelegate.timeZoneId;
59 }
60
61 /**
62 * Returns a {@link TimeZone} object for this mapping, or {@code null} if the ID is
63 * unrecognized.
64 */
65 @Nullable
66 public TimeZone getTimeZone() {
67 return mDelegate.getTimeZone();
68 }
69
70 @Override
71 public boolean equals(Object o) {
72 if (this == o) {
73 return true;
74 }
75 if (o == null || getClass() != o.getClass()) {
76 return false;
77 }
78 TimeZoneMapping that = (TimeZoneMapping) o;
79 return this.mDelegate.equals(that.mDelegate);
80 }
81
82 @Override
83 public int hashCode() {
84 return this.mDelegate.hashCode();
85 }
86
87 @Override
88 public String toString() {
89 return mDelegate.toString();
90 }
91 }
92
93 /**
94 * The result of lookup up a time zone using offset information (and possibly more).
95 *
96 * @hide
97 */
98 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
99 public static final class OffsetResult {
100
101 private final TimeZone mTimeZone;
102 private final boolean mIsOnlyMatch;
103
104 /** Creates an instance with the supplied information. */
105 public OffsetResult(@NonNull TimeZone timeZone, boolean isOnlyMatch) {
106 mTimeZone = Objects.requireNonNull(timeZone);
107 mIsOnlyMatch = isOnlyMatch;
108 }
109
110 /**
111 * Returns a time zone that matches the supplied criteria.
112 */
113 @NonNull
114 public TimeZone getTimeZone() {
115 return mTimeZone;
116 }
117
118 /**
119 * Returns {@code true} if there is only one matching time zone for the supplied criteria.
120 */
121 public boolean isOnlyMatch() {
122 return mIsOnlyMatch;
123 }
124
125 @Override
126 public boolean equals(Object o) {
127 if (this == o) {
128 return true;
129 }
130 if (o == null || getClass() != o.getClass()) {
131 return false;
132 }
133 OffsetResult that = (OffsetResult) o;
134 return mIsOnlyMatch == that.mIsOnlyMatch
135 && mTimeZone.getID().equals(that.mTimeZone.getID());
136 }
137
138 @Override
139 public int hashCode() {
140 return Objects.hash(mTimeZone, mIsOnlyMatch);
141 }
142
143 @Override
144 public String toString() {
145 return "OffsetResult{"
146 + "mTimeZone=" + mTimeZone
147 + ", mIsOnlyMatch=" + mIsOnlyMatch
148 + '}';
149 }
150 }
151
152 @NonNull
153 private final libcore.timezone.CountryTimeZones mDelegate;
154
155 CountryTimeZones(libcore.timezone.CountryTimeZones delegate) {
156 mDelegate = delegate;
157 }
158
159 /**
160 * Returns true if the ISO code for the country is a match for the one specified.
161 */
162 public boolean isForCountryCode(@NonNull String countryIso) {
163 return mDelegate.isForCountryCode(countryIso);
164 }
165
166 /**
167 * Returns the default time zone ID for the country. Can return {@code null} in cases when no
168 * data is available or the time zone ID was not recognized.
169 */
170 @Nullable
171 public String getDefaultTimeZoneId() {
172 return mDelegate.getDefaultTimeZoneId();
173 }
174
175 /**
176 * Returns the default time zone for the country. Can return {@code null} in cases when no data
177 * is available or the time zone ID was not recognized.
178 */
179 @Nullable
180 public TimeZone getDefaultTimeZone() {
181 return mDelegate.getDefaultTimeZone();
182 }
183
184 /**
185 * Qualifier for a country's default time zone. {@code true} indicates whether the default
186 * would be a good choice <em>generally</em> when there's no other information available.
187 */
188 public boolean isDefaultTimeZoneBoosted() {
189 return mDelegate.getDefaultTimeZoneBoost();
190 }
191
192 /**
193 * Returns true if the country has at least one zone that is the same as UTC at the given time.
194 */
195 public boolean hasUtcZone(long whenMillis) {
196 return mDelegate.hasUtcZone(whenMillis);
197 }
198
199 /**
200 * Returns a time zone for the country, if there is one, that matches the desired properties. If
201 * there are multiple matches and the {@code bias} is one of them then it is returned, otherwise
202 * an arbitrary match is returned based on the {@link #getEffectiveTimeZoneMappingsAt(long)}
203 * ordering.
204 *
205 * @param totalOffsetMillis the offset from UTC at {@code whenMillis}
206 * @param isDst the Daylight Savings Time state at {@code whenMillis}. {@code true} means DST,
207 * {@code false} means not DST, {@code null} means unknown
208 * @param dstOffsetMillis the part of {@code totalOffsetMillis} contributed by DST, only used if
209 * {@code isDst} is {@code true}. The value can be {@code null} if the DST offset is
210 * unknown
211 * @param whenMillis the UTC time to match against
212 * @param bias the time zone to prefer, can be {@code null}
213 */
214 @Nullable
215 public OffsetResult lookupByOffsetWithBias(int totalOffsetMillis, @Nullable Boolean isDst,
216 @SuppressLint("AutoBoxing") @Nullable Integer dstOffsetMillis, long whenMillis,
217 @Nullable TimeZone bias) {
218 libcore.timezone.CountryTimeZones.OffsetResult delegateOffsetResult =
219 mDelegate.lookupByOffsetWithBias(
220 totalOffsetMillis, isDst, dstOffsetMillis, whenMillis, bias);
221 return delegateOffsetResult == null ? null :
222 new OffsetResult(delegateOffsetResult.mTimeZone, delegateOffsetResult.mOneMatch);
223 }
224
225 /**
226 * Returns an immutable, ordered list of time zone mappings for the country in an undefined but
227 * "priority" order, filtered so that only "effective" time zone IDs are returned. An
228 * "effective" time zone is one that differs from another time zone used in the country after
229 * {@code whenMillis}. The list can be empty if there were no zones configured or the configured
230 * zone IDs were not recognized.
231 */
232 @NonNull
233 public List<TimeZoneMapping> getEffectiveTimeZoneMappingsAt(long whenMillis) {
234 List<libcore.timezone.CountryTimeZones.TimeZoneMapping> delegateList =
235 mDelegate.getEffectiveTimeZoneMappingsAt(whenMillis);
236
237 List<TimeZoneMapping> toReturn = new ArrayList<>(delegateList.size());
238 for (libcore.timezone.CountryTimeZones.TimeZoneMapping delegateMapping : delegateList) {
239 toReturn.add(new TimeZoneMapping(delegateMapping));
240 }
241 return Collections.unmodifiableList(toReturn);
242 }
243
244 @Override
245 public boolean equals(Object o) {
246 if (this == o) {
247 return true;
248 }
249 if (o == null || getClass() != o.getClass()) {
250 return false;
251 }
252 CountryTimeZones that = (CountryTimeZones) o;
253 return mDelegate.equals(that.mDelegate);
254 }
255
256 @Override
257 public int hashCode() {
258 return Objects.hash(mDelegate);
259 }
260
261 @Override
262 public String toString() {
263 return mDelegate.toString();
264 }
265}