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