blob: 5875761bb1c96d2ce41cb15b8c5cb1bc925001db [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
Neil Fuller2551c032020-01-16 18:39:17 +000046 @NonNull
Neil Fullerf7346ec2019-08-30 18:02:47 +010047 private libcore.timezone.CountryTimeZones.TimeZoneMapping mDelegate;
48
49 TimeZoneMapping(libcore.timezone.CountryTimeZones.TimeZoneMapping delegate) {
50 this.mDelegate = Objects.requireNonNull(delegate);
51 }
52
53 /**
54 * Returns the ID for this mapping. See also {@link #getTimeZone()} which handles when the
55 * ID is unrecognized.
56 */
57 @NonNull
58 public String getTimeZoneId() {
Neil Fuller4720cf02020-01-28 15:05:35 +000059 return mDelegate.getTimeZoneId();
Neil Fullerf7346ec2019-08-30 18:02:47 +010060 }
61
62 /**
63 * Returns a {@link TimeZone} object for this mapping, or {@code null} if the ID is
64 * unrecognized.
65 */
66 @Nullable
67 public TimeZone getTimeZone() {
68 return mDelegate.getTimeZone();
69 }
70
71 @Override
72 public boolean equals(Object o) {
73 if (this == o) {
74 return true;
75 }
76 if (o == null || getClass() != o.getClass()) {
77 return false;
78 }
79 TimeZoneMapping that = (TimeZoneMapping) o;
80 return this.mDelegate.equals(that.mDelegate);
81 }
82
83 @Override
84 public int hashCode() {
85 return this.mDelegate.hashCode();
86 }
87
88 @Override
89 public String toString() {
90 return mDelegate.toString();
91 }
92 }
93
94 /**
95 * The result of lookup up a time zone using offset information (and possibly more).
96 *
97 * @hide
98 */
99 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
100 public static final class OffsetResult {
101
102 private final TimeZone mTimeZone;
103 private final boolean mIsOnlyMatch;
104
105 /** Creates an instance with the supplied information. */
106 public OffsetResult(@NonNull TimeZone timeZone, boolean isOnlyMatch) {
107 mTimeZone = Objects.requireNonNull(timeZone);
108 mIsOnlyMatch = isOnlyMatch;
109 }
110
111 /**
112 * Returns a time zone that matches the supplied criteria.
113 */
114 @NonNull
115 public TimeZone getTimeZone() {
116 return mTimeZone;
117 }
118
119 /**
120 * Returns {@code true} if there is only one matching time zone for the supplied criteria.
121 */
122 public boolean isOnlyMatch() {
123 return mIsOnlyMatch;
124 }
125
126 @Override
127 public boolean equals(Object o) {
128 if (this == o) {
129 return true;
130 }
131 if (o == null || getClass() != o.getClass()) {
132 return false;
133 }
134 OffsetResult that = (OffsetResult) o;
135 return mIsOnlyMatch == that.mIsOnlyMatch
136 && mTimeZone.getID().equals(that.mTimeZone.getID());
137 }
138
139 @Override
140 public int hashCode() {
141 return Objects.hash(mTimeZone, mIsOnlyMatch);
142 }
143
144 @Override
145 public String toString() {
146 return "OffsetResult{"
147 + "mTimeZone=" + mTimeZone
148 + ", mIsOnlyMatch=" + mIsOnlyMatch
149 + '}';
150 }
151 }
152
153 @NonNull
154 private final libcore.timezone.CountryTimeZones mDelegate;
155
156 CountryTimeZones(libcore.timezone.CountryTimeZones delegate) {
157 mDelegate = delegate;
158 }
159
160 /**
161 * Returns true if the ISO code for the country is a match for the one specified.
162 */
163 public boolean isForCountryCode(@NonNull String countryIso) {
164 return mDelegate.isForCountryCode(countryIso);
165 }
166
167 /**
168 * Returns the default time zone ID for the country. Can return {@code null} in cases when no
169 * data is available or the time zone ID was not recognized.
170 */
171 @Nullable
172 public String getDefaultTimeZoneId() {
173 return mDelegate.getDefaultTimeZoneId();
174 }
175
176 /**
177 * Returns the default time zone for the country. Can return {@code null} in cases when no data
178 * is available or the time zone ID was not recognized.
179 */
180 @Nullable
181 public TimeZone getDefaultTimeZone() {
182 return mDelegate.getDefaultTimeZone();
183 }
184
185 /**
186 * Qualifier for a country's default time zone. {@code true} indicates whether the default
187 * would be a good choice <em>generally</em> when there's no other information available.
188 */
189 public boolean isDefaultTimeZoneBoosted() {
Neil Fuller4720cf02020-01-28 15:05:35 +0000190 return mDelegate.isDefaultTimeZoneBoosted();
Neil Fullerf7346ec2019-08-30 18:02:47 +0100191 }
192
193 /**
194 * Returns true if the country has at least one zone that is the same as UTC at the given time.
195 */
196 public boolean hasUtcZone(long whenMillis) {
197 return mDelegate.hasUtcZone(whenMillis);
198 }
199
200 /**
201 * Returns a time zone for the country, if there is one, that matches the desired properties. If
202 * there are multiple matches and the {@code bias} is one of them then it is returned, otherwise
203 * an arbitrary match is returned based on the {@link #getEffectiveTimeZoneMappingsAt(long)}
204 * ordering.
205 *
206 * @param totalOffsetMillis the offset from UTC at {@code whenMillis}
207 * @param isDst the Daylight Savings Time state at {@code whenMillis}. {@code true} means DST,
208 * {@code false} means not DST, {@code null} means unknown
209 * @param dstOffsetMillis the part of {@code totalOffsetMillis} contributed by DST, only used if
210 * {@code isDst} is {@code true}. The value can be {@code null} if the DST offset is
211 * unknown
212 * @param whenMillis the UTC time to match against
213 * @param bias the time zone to prefer, can be {@code null}
214 */
215 @Nullable
216 public OffsetResult lookupByOffsetWithBias(int totalOffsetMillis, @Nullable Boolean isDst,
217 @SuppressLint("AutoBoxing") @Nullable Integer dstOffsetMillis, long whenMillis,
218 @Nullable TimeZone bias) {
219 libcore.timezone.CountryTimeZones.OffsetResult delegateOffsetResult =
220 mDelegate.lookupByOffsetWithBias(
221 totalOffsetMillis, isDst, dstOffsetMillis, whenMillis, bias);
222 return delegateOffsetResult == null ? null :
Neil Fuller4720cf02020-01-28 15:05:35 +0000223 new OffsetResult(
224 delegateOffsetResult.getTimeZone(), delegateOffsetResult.isOnlyMatch());
Neil Fullerf7346ec2019-08-30 18:02:47 +0100225 }
226
227 /**
228 * Returns an immutable, ordered list of time zone mappings for the country in an undefined but
229 * "priority" order, filtered so that only "effective" time zone IDs are returned. An
230 * "effective" time zone is one that differs from another time zone used in the country after
231 * {@code whenMillis}. The list can be empty if there were no zones configured or the configured
232 * zone IDs were not recognized.
233 */
234 @NonNull
235 public List<TimeZoneMapping> getEffectiveTimeZoneMappingsAt(long whenMillis) {
236 List<libcore.timezone.CountryTimeZones.TimeZoneMapping> delegateList =
237 mDelegate.getEffectiveTimeZoneMappingsAt(whenMillis);
238
239 List<TimeZoneMapping> toReturn = new ArrayList<>(delegateList.size());
240 for (libcore.timezone.CountryTimeZones.TimeZoneMapping delegateMapping : delegateList) {
241 toReturn.add(new TimeZoneMapping(delegateMapping));
242 }
243 return Collections.unmodifiableList(toReturn);
244 }
245
246 @Override
247 public boolean equals(Object o) {
248 if (this == o) {
249 return true;
250 }
251 if (o == null || getClass() != o.getClass()) {
252 return false;
253 }
254 CountryTimeZones that = (CountryTimeZones) o;
255 return mDelegate.equals(that.mDelegate);
256 }
257
258 @Override
259 public int hashCode() {
260 return Objects.hash(mDelegate);
261 }
262
263 @Override
264 public String toString() {
265 return mDelegate.toString();
266 }
267}