1 /*
2  * Copyright (C) 2017 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 package com.android.settings.datetime.timezone;
17 
18 import android.icu.text.TimeZoneFormat;
19 import android.icu.text.TimeZoneNames;
20 import android.icu.util.TimeZone;
21 import android.text.TextUtils;
22 
23 import com.android.settingslib.datetime.ZoneGetter;
24 
25 import java.util.Date;
26 import java.util.Locale;
27 
28 /**
29  * Data object containing information for displaying a time zone for the user to select.
30  */
31 public class TimeZoneInfo {
32 
33     private final String mId;
34     private final TimeZone mTimeZone;
35     private final String mGenericName;
36     private final String mStandardName;
37     private final String mDaylightName;
38     private final String mExemplarLocation;
39     private final CharSequence mGmtOffset;
40 
TimeZoneInfo(Builder builder)41     public TimeZoneInfo(Builder builder) {
42         mTimeZone = builder.mTimeZone;
43         mId = mTimeZone.getID();
44         mGenericName = builder.mGenericName;
45         mStandardName = builder.mStandardName;
46         mDaylightName = builder.mDaylightName;
47         mExemplarLocation = builder.mExemplarLocation;
48         mGmtOffset = builder.mGmtOffset;
49     }
50 
getId()51     public String getId() {
52         return mId;
53     }
54 
getTimeZone()55     public TimeZone getTimeZone() {
56         return mTimeZone;
57     }
58 
getExemplarLocation()59     public String getExemplarLocation() {
60         return mExemplarLocation;
61     }
62 
getGenericName()63     public String getGenericName() {
64         return mGenericName;
65     }
66 
getStandardName()67     public String getStandardName() {
68         return mStandardName;
69     }
70 
getDaylightName()71     public String getDaylightName() {
72         return mDaylightName;
73     }
74 
getGmtOffset()75     public CharSequence getGmtOffset() {
76         return mGmtOffset;
77     }
78 
79     public static class Builder {
80         private final TimeZone mTimeZone;
81         private String mGenericName;
82         private String mStandardName;
83         private String mDaylightName;
84         private String mExemplarLocation;
85         private CharSequence mGmtOffset;
86 
Builder(TimeZone timeZone)87         public Builder(TimeZone timeZone) {
88             if (timeZone == null) {
89                 throw new IllegalArgumentException("TimeZone must not be null!");
90             }
91             mTimeZone = timeZone;
92         }
93 
setGenericName(String genericName)94         public Builder setGenericName(String genericName) {
95             this.mGenericName = genericName;
96             return this;
97         }
98 
setStandardName(String standardName)99         public Builder setStandardName(String standardName) {
100             this.mStandardName = standardName;
101             return this;
102         }
103 
setDaylightName(String daylightName)104         public Builder setDaylightName(String daylightName) {
105             mDaylightName = daylightName;
106             return this;
107         }
108 
setExemplarLocation(String exemplarLocation)109         public Builder setExemplarLocation(String exemplarLocation) {
110             mExemplarLocation = exemplarLocation;
111             return this;
112         }
113 
setGmtOffset(CharSequence gmtOffset)114         public Builder setGmtOffset(CharSequence gmtOffset) {
115             mGmtOffset = gmtOffset;
116             return this;
117         }
118 
build()119         public TimeZoneInfo build() {
120             if (TextUtils.isEmpty(mGmtOffset)) {
121                 throw new IllegalStateException("gmtOffset must not be empty!");
122             }
123             return new TimeZoneInfo(this);
124         }
125     }
126 
127     public static class Formatter {
128         private final Locale mLocale;
129         private final Date mNow;
130         private final TimeZoneFormat mTimeZoneFormat;
131 
Formatter(Locale locale, Date now)132         public Formatter(Locale locale, Date now) {
133             mLocale = locale;
134             mNow = now;
135             mTimeZoneFormat = TimeZoneFormat.getInstance(locale);
136         }
137 
138         /**
139          * @param timeZoneId Olson time zone id
140          * @return TimeZoneInfo containing time zone names, exemplar locations and GMT offset
141          */
format(String timeZoneId)142         public TimeZoneInfo format(String timeZoneId) {
143             TimeZone timeZone = TimeZone.getFrozenTimeZone(timeZoneId);
144             return format(timeZone);
145         }
146 
147         /**
148          * @param timeZone Olson time zone object
149          * @return TimeZoneInfo containing time zone names, exemplar locations and GMT offset
150          */
format(TimeZone timeZone)151         public TimeZoneInfo format(TimeZone timeZone) {
152             String canonicalZoneId = getCanonicalZoneId(timeZone);
153             final TimeZoneNames timeZoneNames = mTimeZoneFormat.getTimeZoneNames();
154             final java.util.TimeZone javaTimeZone = java.util.TimeZone.getTimeZone(canonicalZoneId);
155             final CharSequence gmtOffset = ZoneGetter.getGmtOffsetText(mTimeZoneFormat, mLocale,
156                 javaTimeZone, mNow);
157             return new TimeZoneInfo.Builder(timeZone)
158                     .setGenericName(timeZoneNames.getDisplayName(canonicalZoneId,
159                             TimeZoneNames.NameType.LONG_GENERIC, mNow.getTime()))
160                     .setStandardName(timeZoneNames.getDisplayName(canonicalZoneId,
161                             TimeZoneNames.NameType.LONG_STANDARD, mNow.getTime()))
162                     .setDaylightName(timeZoneNames.getDisplayName(canonicalZoneId,
163                             TimeZoneNames.NameType.LONG_DAYLIGHT, mNow.getTime()))
164                     .setExemplarLocation(timeZoneNames.getExemplarLocationName(canonicalZoneId))
165                     .setGmtOffset(gmtOffset)
166                     .build();
167         }
168 
getCanonicalZoneId(TimeZone timeZone)169         private static String getCanonicalZoneId(TimeZone timeZone) {
170             final String id = timeZone.getID();
171             final String canonicalId = TimeZone.getCanonicalID(id);
172             if (canonicalId != null) {
173                 return canonicalId;
174             }
175             return id;
176         }
177     }
178 
179 }
180