TimeZoneData.java revision 1989c63ae3f98b5088e27564cd397ef5e8affaea
1b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan/* 2b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * Copyright (C) 2013 The Android Open Source Project 3b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * 4b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * Licensed under the Apache License, Version 2.0 (the "License"); 5b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * you may not use this file except in compliance with the License. 6b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * You may obtain a copy of the License at 7b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * 8b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * http://www.apache.org/licenses/LICENSE-2.0 9b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * 10b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * Unless required by applicable law or agreed to in writing, software 11b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * distributed under the License is distributed on an "AS IS" BASIS, 12b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * See the License for the specific language governing permissions and 14b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * limitations under the License. 15b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan */ 16b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 17b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanpackage com.android.timezonepicker; 18b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 19b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.content.Context; 20b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.content.res.AssetManager; 211989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chanimport android.content.res.Resources; 22b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.text.format.DateFormat; 23b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.text.format.DateUtils; 24b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.util.Log; 25b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.util.SparseArray; 26b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 27b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.io.BufferedReader; 28b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.io.IOException; 29b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.io.InputStream; 30b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.io.InputStreamReader; 31b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.ArrayList; 32b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.Collections; 33b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.Date; 34b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.HashMap; 35b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.HashSet; 36b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.LinkedHashMap; 37b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.Locale; 38b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.TimeZone; 39b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 40b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanpublic class TimeZoneData { 41b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private static final String TAG = "TimeZoneData"; 42b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private static final boolean DEBUG = false; 43b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private static final int OFFSET_ARRAY_OFFSET = 20; 44b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 45b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan ArrayList<TimeZoneInfo> mTimeZones; 46b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan LinkedHashMap<String, ArrayList<Integer>> mTimeZonesByCountry; 47b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan HashSet<String> mTimeZoneNames = new HashSet<String>(); 48b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 49b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private long mTimeMillis; 50b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private HashMap<String, String> mCountryCodeToNameMap = new HashMap<String, String>(); 51b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 52b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public String mDefaultTimeZoneId; 53b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public static boolean is24HourFormat; 54b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private TimeZoneInfo mDefaultTimeZoneInfo; 55b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private String mAlternateDefaultTimeZoneId; 56b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private String mDefaultTimeZoneCountry; 571989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan private HashMap<String, TimeZoneInfo> mTimeZonesById; 581989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan private boolean[] mHasTimeZonesInHrOffset = new boolean[40]; 591989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan SparseArray<ArrayList<Integer>> mTimeZonesByOffsets; 601989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan private Context mContext; 61b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 62b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public TimeZoneData(Context context, String defaultTimeZoneId, long timeMillis) { 631989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan mContext = context; 64b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan is24HourFormat = TimeZoneInfo.is24HourFormat = DateFormat.is24HourFormat(context); 65b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mDefaultTimeZoneId = mAlternateDefaultTimeZoneId = defaultTimeZoneId; 66b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan long now = System.currentTimeMillis(); 67b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 68b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (timeMillis == 0) { 69b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeMillis = now; 70b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else { 71b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeMillis = timeMillis; 72b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 73b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan loadTzs(context); 741989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan 75b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.i(TAG, "Time to load time zones (ms): " + (System.currentTimeMillis() - now)); 76b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 77b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // now = System.currentTimeMillis(); 78b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // printTz(); 79b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Log.i(TAG, "Time to print time zones (ms): " + 80b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // (System.currentTimeMillis() - now)); 81b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 82b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 83b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public void setTime(long timeMillis) { 84b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeMillis = timeMillis; 85b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 86b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 87b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public TimeZoneInfo get(int position) { 88b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return mTimeZones.get(position); 89b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 90b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 91b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public int size() { 92b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return mTimeZones.size(); 93b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 94b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 95b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public int getDefaultTimeZoneIndex() { 96b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return mTimeZones.indexOf(mDefaultTimeZoneInfo); 97b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 98b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 99b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // TODO speed this up 100b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public int findIndexByTimeZoneIdSlow(String timeZoneId) { 101b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int idx = 0; 102b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan for (TimeZoneInfo tzi : mTimeZones) { 103b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (timeZoneId.equals(tzi.mTzId)) { 104b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return idx; 105b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 106b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan idx++; 107b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 108b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return -1; 109b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 110b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 111b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan void loadTzs(Context context) { 112b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeZones = new ArrayList<TimeZoneInfo>(); 113b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan HashSet<String> processedTimeZones = loadTzsInZoneTab(context); 114b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan String[] tzIds = TimeZone.getAvailableIDs(); 115b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 116b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (DEBUG) { 117b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "Available time zones: " + tzIds.length); 118b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 119b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 120b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan for (String tzId : tzIds) { 121b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (processedTimeZones.contains(tzId)) { 122b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan continue; 123b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 124b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 1251989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan /* 1261989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan * Dropping non-GMT tzs without a country code. They are not 1271989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan * really needed and they are dups but missing proper 1281989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan * country codes. e.g. WET CET MST7MDT PST8PDT Asia/Khandyga 1291989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan * Asia/Ust-Nera EST 1301989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan */ 1311989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan if (!tzId.startsWith("Etc/GMT")) { 1321989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan continue; 1331989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan } 1341989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan 135b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan final TimeZone tz = TimeZone.getTimeZone(tzId); 136b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (tz == null) { 137b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "Timezone not found: " + tzId); 138b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan continue; 139b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 140b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 141b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan TimeZoneInfo tzInfo = new TimeZoneInfo(tz, null); 142b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 143b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (getIdenticalTimeZoneInTheCountry(tzInfo) == -1) { 144b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (DEBUG) { 145b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "# Adding time zone from getAvailId: " + tzInfo.toString()); 146b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 147b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeZones.add(tzInfo); 148b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else { 149b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (DEBUG) { 150b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, 151b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan "# Dropping identical time zone from getAvailId: " + tzInfo.toString()); 152b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 153b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan continue; 154b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 155b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 156b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // TODO check for dups 157b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // checkForNameDups(tz, tzInfo.mCountry, false /* dls */, 158b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // TimeZone.SHORT, groupIdx, !found); 159b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // checkForNameDups(tz, tzInfo.mCountry, false /* dls */, 160b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // TimeZone.LONG, groupIdx, !found); 161b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // if (tz.useDaylightTime()) { 162b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // checkForNameDups(tz, tzInfo.mCountry, true /* dls */, 163b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // TimeZone.SHORT, groupIdx, 164b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // !found); 165b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // checkForNameDups(tz, tzInfo.mCountry, true /* dls */, 166b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // TimeZone.LONG, groupIdx, 167b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // !found); 168b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // } 169b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 170b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 171b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Don't change the order of mTimeZones after this sort 172b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Collections.sort(mTimeZones); 1731989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // TimeZoneInfo last = null; 1741989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // boolean first = true; 1751989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // for (TimeZoneInfo tz : mTimeZones) { 1761989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // // All 1771989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // Log.e("ALL", tz.toString()); 1781989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // 1791989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // // GMT 1801989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // String name = tz.mTz.getDisplayName(); 1811989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // if (name.startsWith("GMT") && !tz.mTzId.startsWith("Etc/GMT")) { 1821989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // Log.e("GMT", tz.toString()); 1831989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // } 1841989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // 1851989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // // Dups 1861989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // if (last != null) { 1871989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // if (last.compareTo(tz) == 0) { 1881989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // if (first) { 1891989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // Log.e("SAME", last.toString()); 1901989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // first = false; 1911989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // } 1921989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // Log.e("SAME", tz.toString()); 1931989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // } else { 1941989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // first = true; 1951989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // } 1961989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // } 1971989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // last = tz; 1981989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // } 199b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 200b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeZonesByCountry = new LinkedHashMap<String, ArrayList<Integer>>(); 201b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeZonesByOffsets = new SparseArray<ArrayList<Integer>>(mHasTimeZonesInHrOffset.length); 2021989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan mTimeZonesById = new HashMap<String, TimeZoneInfo>(mTimeZones.size()); 2031989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan for (TimeZoneInfo tz : mTimeZones) { 2041989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // ///////////////////// 2051989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // Lookup map for id -> tz 2061989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan mTimeZonesById.put(tz.mTzId, tz); 2071989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan } 2081989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan populateDisplayNameOverrides(mContext.getResources()); 209b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 210b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Date date = new Date(mTimeMillis); 211b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Locale defaultLocal = Locale.getDefault(); 212b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 213b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int idx = 0; 214b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan for (TimeZoneInfo tz : mTimeZones) { 2151989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // ///////////////////// 2161989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan // Populate display name 2171989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan if (tz.mDisplayName == null) { 2181989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan tz.mDisplayName = tz.mTz.getDisplayName(tz.mTz.inDaylightTime(date), 2191989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan TimeZone.LONG, defaultLocal); 2201989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan } 221b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 222b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // ///////////////////// 223b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Grouping tz's by country for search by country 224b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan ArrayList<Integer> group = mTimeZonesByCountry.get(tz.mCountry); 225b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (group == null) { 226b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan group = new ArrayList<Integer>(); 227b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeZonesByCountry.put(tz.mCountry, group); 228b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 229b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 230b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan group.add(idx); 231b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 232b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // ///////////////////// 233b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Grouping tz's by GMT offsets 234b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan indexByOffsets(idx, tz); 235b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 236b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Skip all the GMT+xx:xx style display names from search 237b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (!tz.mDisplayName.endsWith(":00")) { 238b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeZoneNames.add(tz.mDisplayName); 239b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else if (DEBUG) { 240b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "# Hiding from pretty name search: " + 241b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan tz.mDisplayName); 242b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 243b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 244b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan idx++; 245b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 246b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 247b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 2481989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan private void populateDisplayNameOverrides(Resources resources) { 2491989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan String[] ids = resources.getStringArray(R.array.timezone_rename_ids); 2501989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan String[] labels = resources.getStringArray(R.array.timezone_rename_labels); 2511989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan 2521989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan int length = ids.length; 2531989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan if (ids.length != labels.length) { 2541989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan Log.e(TAG, "timezone_rename_ids len=" + ids.length + " timezone_rename_labels len=" 2551989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan + labels.length); 2561989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan length = Math.min(ids.length, labels.length); 2571989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan } 2581989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan 2591989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan for (int i = 0; i < length; i++) { 2601989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan TimeZoneInfo tzi = mTimeZonesById.get(ids[i]); 2611989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan tzi.mDisplayName = labels[i]; 2621989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan } 2631989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan } 264b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 265b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public boolean hasTimeZonesInHrOffset(int offsetHr) { 266b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int index = OFFSET_ARRAY_OFFSET + offsetHr; 267b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (index >= mHasTimeZonesInHrOffset.length || index < 0) { 268b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return false; 269b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 270b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return mHasTimeZonesInHrOffset[index]; 271b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 272b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 273b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private void indexByOffsets(int idx, TimeZoneInfo tzi) { 274b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int offsetMillis = tzi.getNowOffsetMillis(); 275b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int index = OFFSET_ARRAY_OFFSET + (int) (offsetMillis / DateUtils.HOUR_IN_MILLIS); 276b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mHasTimeZonesInHrOffset[index] = true; 277b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 278b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan ArrayList<Integer> group = mTimeZonesByOffsets.get(index); 279b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (group == null) { 280b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan group = new ArrayList<Integer>(); 281b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeZonesByOffsets.put(index, group); 282b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 283b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan group.add(idx); 284b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 285b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 286b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public ArrayList<Integer> getTimeZonesByOffset(int offsetHr) { 287b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int index = OFFSET_ARRAY_OFFSET + offsetHr; 288b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (index >= mHasTimeZonesInHrOffset.length || index < 0) { 289b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return null; 290b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 291b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return mTimeZonesByOffsets.get(index); 292b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 293b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 294b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private HashSet<String> loadTzsInZoneTab(Context context) { 295b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan HashSet<String> processedTimeZones = new HashSet<String>(); 296b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan AssetManager am = context.getAssets(); 297b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan InputStream is = null; 298b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 299b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan /* 300b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * The 'backward' file contain mappings between new and old time zone 301b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * ids. We will explicitly ignore the old ones. 302b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan */ 303b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan try { 304b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan is = am.open("backward"); 305b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 306b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan String line; 307b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 308b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan while ((line = reader.readLine()) != null) { 309b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Skip comment lines 310b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (!line.startsWith("#") && line.length() > 0) { 311b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 0: "Link" 312b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 1: New tz id 313b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Last: Old tz id 314b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan String[] fields = line.split("\t+"); 315b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan String newTzId = fields[1]; 316b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan String oldTzId = fields[fields.length - 1]; 317b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 318b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan final TimeZone tz = TimeZone.getTimeZone(newTzId); 319b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (tz == null) { 320b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "Timezone not found: " + newTzId); 321b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan continue; 322b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 323b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 324b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan processedTimeZones.add(oldTzId); 325b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 326b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (DEBUG) { 327b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "# Dropping identical time zone from backward: " + oldTzId); 328b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 329b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 330b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Remember the cooler/newer time zone id 331b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (mDefaultTimeZoneId != null && mDefaultTimeZoneId.equals(oldTzId)) { 332b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mAlternateDefaultTimeZoneId = newTzId; 333b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 334b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 335b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 336b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } catch (IOException ex) { 337b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "Failed to read 'backward' file."); 338b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } finally { 339b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan try { 340b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (is != null) { 341b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan is.close(); 342b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 343b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } catch (IOException ignored) { 344b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 345b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 346b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 347b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan /* 348b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * zone.tab contains a list of time zones and country code. They are 349b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * "sorted first by country, then an order within the country that (1) 350b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * makes some geographical sense, and (2) puts the most populous zones 351b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * first, where that does not contradict (1)." 352b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan */ 353b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan try { 354b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan String lang = Locale.getDefault().getLanguage(); 355b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan is = am.open("zone.tab"); 356b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 357b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan String line; 358b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan while ((line = reader.readLine()) != null) { 359b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (!line.startsWith("#")) { // Skip comment lines 360b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 0: country code 361b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 1: coordinates 362b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 2: time zone id 363b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 3: comments 364b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan final String[] fields = line.split("\t"); 365b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan final String timeZoneId = fields[2]; 366b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan final String countryCode = fields[0]; 367b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan final TimeZone tz = TimeZone.getTimeZone(timeZoneId); 368b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (tz == null) { 369b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "Timezone not found: " + timeZoneId); 370b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan continue; 371b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 372b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 3731989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan /* 3741989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan * Dropping non-GMT tzs without a country code. They are not 3751989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan * really needed and they are dups but missing proper 3761989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan * country codes. e.g. WET CET MST7MDT PST8PDT Asia/Khandyga 3771989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan * Asia/Ust-Nera EST 3781989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan */ 3791989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan if (countryCode == null && !timeZoneId.startsWith("Etc/GMT")) { 3801989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan processedTimeZones.add(timeZoneId); 3811989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan continue; 3821989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan } 3831989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan 384b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Remember the mapping between the country code and display 385b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // name 3861989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan String country = mCountryCodeToNameMap.get(countryCode); 387b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (country == null) { 388b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan country = new Locale(lang, countryCode) 389b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan .getDisplayCountry(Locale.getDefault()); 390b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mCountryCodeToNameMap.put(countryCode, country); 391b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 392b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 393b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // TODO Don't like this here but need to get the country of 394b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // the default tz. 395b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 396b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Find the country of the default tz 397b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (mDefaultTimeZoneId != null && mDefaultTimeZoneCountry == null 398b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan && timeZoneId.equals(mAlternateDefaultTimeZoneId)) { 399b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mDefaultTimeZoneCountry = country; 400b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan TimeZone defaultTz = TimeZone.getTimeZone(mDefaultTimeZoneId); 401b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (defaultTz != null) { 402b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mDefaultTimeZoneInfo = new TimeZoneInfo(defaultTz, country); 403b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 404b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int tzToOverride = getIdenticalTimeZoneInTheCountry(mDefaultTimeZoneInfo); 405b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (tzToOverride == -1) { 406b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (DEBUG) { 407b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "Adding default time zone: " 408b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan + mDefaultTimeZoneInfo.toString()); 409b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 410b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeZones.add(mDefaultTimeZoneInfo); 411b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else { 412b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeZones.add(tzToOverride, mDefaultTimeZoneInfo); 413b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (DEBUG) { 414b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan TimeZoneInfo tzInfoToOverride = mTimeZones.get(tzToOverride); 415b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan String tzIdToOverride = tzInfoToOverride.mTzId; 416b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "Replaced by default tz: " 417b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan + tzInfoToOverride.toString()); 418b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "Adding default time zone: " 419b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan + mDefaultTimeZoneInfo.toString()); 420b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 421b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 422b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 423b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 424b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 425b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Add to the list of time zones if the time zone is unique 426b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // in the given country. 427b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan TimeZoneInfo timeZoneInfo = new TimeZoneInfo(tz, country); 428b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int identicalTzIdx = getIdenticalTimeZoneInTheCountry(timeZoneInfo); 429b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (identicalTzIdx == -1) { 430b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (DEBUG) { 431b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "# Adding time zone: " + timeZoneId + " ## " + 432b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan tz.getDisplayName()); 433b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 434b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTimeZones.add(timeZoneInfo); 435b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else { 436b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (DEBUG) { 437b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "# Dropping identical time zone: " + timeZoneId + " ## " + 438b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan tz.getDisplayName()); 439b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 440b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 441b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan processedTimeZones.add(timeZoneId); 442b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 443b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 444b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 445b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } catch (IOException ex) { 446b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "Failed to read 'zone.tab'."); 447b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } finally { 448b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan try { 449b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (is != null) { 450b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan is.close(); 451b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 452b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } catch (IOException ignored) { 453b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 454b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 455b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 456b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return processedTimeZones; 457b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 458b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 459b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private int getIdenticalTimeZoneInTheCountry(TimeZoneInfo timeZoneInfo) { 460b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int idx = 0; 461b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan for (TimeZoneInfo tzi : mTimeZones) { 462b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (tzi.hasSameRules(timeZoneInfo)) { 463b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (tzi.mCountry == null) { 464b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (timeZoneInfo.mCountry == null) { 465b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return idx; 466b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 467b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else if (tzi.mCountry.equals(timeZoneInfo.mCountry)) { 468b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return idx; 469b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 470b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 471b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan ++idx; 472b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 473b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return -1; 474b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 475b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 476b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private void printTz() { 477b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan for (TimeZoneInfo tz : mTimeZones) { 478b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "" + tz.toString()); 479b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 480b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 481b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan Log.e(TAG, "Total number of tz's = " + mTimeZones.size()); 482b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 483b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 484b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // void checkForNameDups(TimeZone tz, String country, boolean dls, int 485b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // style, int idx, 486b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // boolean print) { 487b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // if (country == null) { 488b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // return; 489b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // } 490b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // String displayName = tz.getDisplayName(dls, style); 491b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 492b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // if (print) { 493b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Log.e(TAG, "" + idx + " " + tz.getID() + " " + country + " ## " + 494b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // displayName); 495b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // } 496b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 497b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // if (tz.useDaylightTime()) { 498b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // if (displayName.matches("GMT[+-][0-9][0-9]:[0-9][0-9]")) { 499b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // return; 500b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // } 501b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 502b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // if (displayName.length() == 3 && displayName.charAt(2) == 'T' && 503b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // (displayName.charAt(1) == 'S' || displayName.charAt(1) == 'D')) { 504b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // displayName = "" + displayName.charAt(0) + 'T'; 505b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // } else { 506b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // displayName = displayName.replace(" Daylight ", 507b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // " ").replace(" Standard ", " "); 508b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // } 509b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // } 510b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 511b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // String tzNameWithCountry = country + " ## " + displayName; 512b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Integer groupId = mCountryPlusTzName2Tzs.get(tzNameWithCountry); 513b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // if (groupId == null) { 514b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // mCountryPlusTzName2Tzs.put(tzNameWithCountry, idx); 515b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // } else if (groupId != idx) { 516b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Log.e(TAG, "Yikes: " + tzNameWithCountry + " matches " + groupId + 517b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // " and " + idx); 518b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // } 519b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // } 520b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 521b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan} 522