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; 20143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chanimport android.text.Spannable; 21143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chanimport android.text.Spannable.Factory; 22b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.text.format.DateUtils; 23b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.text.format.Time; 24143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chanimport android.text.style.ForegroundColorSpan; 25b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.util.Log; 26b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport android.util.SparseArray; 27b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 28b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.lang.reflect.Field; 29b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.text.DateFormat; 30b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.Arrays; 31b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.Date; 32b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.Formatter; 33b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.Locale; 34b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanimport java.util.TimeZone; 35b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 36b1b7080deea42aa533c3757b585cf765c6b76732Michael Chanpublic class TimeZoneInfo implements Comparable<TimeZoneInfo> { 37adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein private static final int GMT_TEXT_COLOR = TimeZonePickerUtils.GMT_TEXT_COLOR; 38adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein private static final int DST_SYMBOL_COLOR = TimeZonePickerUtils.DST_SYMBOL_COLOR; 39b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private static final char SEPARATOR = ','; 40b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private static final String TAG = null; 41b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public static int NUM_OF_TRANSITIONS = 6; 42b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public static long time = System.currentTimeMillis() / 1000; 43b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public static boolean is24HourFormat; 44143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan private static final Factory mSpannableFactory = Spannable.Factory.getInstance(); 45b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 46b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan TimeZone mTz; 47b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public String mTzId; 48b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int mRawoffset; 49b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public String mCountry; 50b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public int groupId; 51b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public String mDisplayName; 52b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private Time recycledTime = new Time(); 53b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private static StringBuilder mSB = new StringBuilder(50); 54b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private static Formatter mFormatter = new Formatter(mSB, Locale.getDefault()); 55b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 56b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public TimeZoneInfo(TimeZone tz, String country) { 57b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTz = tz; 58b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mTzId = tz.getID(); 59b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mCountry = country; 60b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mRawoffset = tz.getRawOffset(); 61b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 62b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 63b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan SparseArray<String> mLocalTimeCache = new SparseArray<String>(); 64b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan long mLocalTimeCacheReferenceTime = 0; 65b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan static private long mGmtDisplayNameUpdateTime; 66143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan static private SparseArray<CharSequence> mGmtDisplayNameCache = 67143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan new SparseArray<CharSequence>(); 68b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 69b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public String getLocalTime(long referenceTime) { 70b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan recycledTime.timezone = TimeZone.getDefault().getID(); 71b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan recycledTime.set(referenceTime); 72b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 73b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int currYearDay = recycledTime.year * 366 + recycledTime.yearDay; 74b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 75b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan recycledTime.timezone = mTzId; 76b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan recycledTime.set(referenceTime); 77b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 78b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan String localTimeStr = null; 79b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 80b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int hourMinute = recycledTime.hour * 60 + 81b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan recycledTime.minute; 82b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 83b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (mLocalTimeCacheReferenceTime != referenceTime) { 84b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mLocalTimeCacheReferenceTime = referenceTime; 85b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mLocalTimeCache.clear(); 86b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else { 87b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan localTimeStr = mLocalTimeCache.get(hourMinute); 88b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 89b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 90b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (localTimeStr == null) { 91b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan String format = "%I:%M %p"; 92b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (currYearDay != (recycledTime.year * 366 + recycledTime.yearDay)) { 93b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (is24HourFormat) { 94b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan format = "%b %d %H:%M"; 95b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else { 96b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan format = "%b %d %I:%M %p"; 97b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 98b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else if (is24HourFormat) { 99b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan format = "%H:%M"; 100b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 101b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 102b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // format = "%Y-%m-%d %H:%M"; 103b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan localTimeStr = recycledTime.format(format); 104b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mLocalTimeCache.put(hourMinute, localTimeStr); 105b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 106b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 107b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return localTimeStr; 108b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 109b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 110b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public int getLocalHr(long referenceTime) { 1110717b65fee21de6a321e42c9f3852f8b622c3215Michael Chan recycledTime.timezone = mTzId; 112b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan recycledTime.set(referenceTime); 113b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return recycledTime.hour; 114b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 115b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 116b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public int getNowOffsetMillis() { 117b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return mTz.getOffset(System.currentTimeMillis()); 118b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 119b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 120b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan /* 121b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * The method is synchronized because there's one mSB, which is used by 122b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * mFormatter, per instance. If there are multiple callers for 123b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * getGmtDisplayName, the output may be mangled. 124b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan */ 125143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan public synchronized CharSequence getGmtDisplayName(Context context) { 126b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // TODO Note: The local time is shown in current time (current GMT 127b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // offset) which may be different from the time specified by 128b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // mTimeMillis 129b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 130b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan final long nowMinute = System.currentTimeMillis() / DateUtils.MINUTE_IN_MILLIS; 131b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan final long now = nowMinute * DateUtils.MINUTE_IN_MILLIS; 132b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan final int gmtOffset = mTz.getOffset(now); 133b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int cacheKey; 134b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 135b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan boolean hasFutureDST = mTz.useDaylightTime(); 136b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (hasFutureDST) { 137b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan cacheKey = (int) (gmtOffset + 36 * DateUtils.HOUR_IN_MILLIS); 138b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else { 139b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan cacheKey = (int) (gmtOffset - 36 * DateUtils.HOUR_IN_MILLIS); 140b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 141b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 142143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan CharSequence displayName = null; 143b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (mGmtDisplayNameUpdateTime != nowMinute) { 144b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mGmtDisplayNameUpdateTime = nowMinute; 145b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mGmtDisplayNameCache.clear(); 146b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else { 147b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan displayName = mGmtDisplayNameCache.get(cacheKey); 148b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 149b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 150b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (displayName == null) { 151b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mSB.setLength(0); 152b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int flags = DateUtils.FORMAT_ABBREV_ALL; 153b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan flags |= DateUtils.FORMAT_SHOW_TIME; 154b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (TimeZoneInfo.is24HourFormat) { 155b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan flags |= DateUtils.FORMAT_24HOUR; 156b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 157b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 158b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // mFormatter writes to mSB 159b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan DateUtils.formatDateRange(context, mFormatter, now, now, flags, mTzId); 1605f2204bc83982ec4ffec0e01efa39325b4fe58aeSam Blitzstein mSB.append(" "); 161adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein int gmtStart = mSB.length(); 162143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan TimeZonePickerUtils.appendGmtOffset(mSB, gmtOffset); 163adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein int gmtEnd = mSB.length(); 164b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 165adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein int symbolStart = 0; 166adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein int symbolEnd = 0; 167b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (hasFutureDST) { 168143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan mSB.append(' '); 169adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein symbolStart = mSB.length(); 170143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan mSB.append(TimeZonePickerUtils.getDstSymbol()); // Sun symbol 171adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein symbolEnd = mSB.length(); 172adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein } 173adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein 174adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein // Set the gray colors. 175adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein Spannable spannableText = mSpannableFactory.newSpannable(mSB); 176adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein spannableText.setSpan(new ForegroundColorSpan(GMT_TEXT_COLOR), 177adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein gmtStart, gmtEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 178143a7e20a46dbd66bec4e4d7e8e0dcb693d343d3Michael Chan 179adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein if (hasFutureDST) { 180adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein spannableText.setSpan(new ForegroundColorSpan(DST_SYMBOL_COLOR), 181adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein symbolStart, symbolEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 182b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 183adbe2ac08b1456d2ed2e4adc2afa9c078a3e028eSam Blitzstein displayName = spannableText; 184b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan mGmtDisplayNameCache.put(cacheKey, displayName); 185b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 186b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return displayName; 187b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 188b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 189b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public boolean hasSameRules(TimeZoneInfo tzi) { 1903a54ae0f42d50e3b855139a3439f2965506c9c2aSam Blitzstein return this.mTz.hasSameRules(tzi.mTz); 191b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 192b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 193b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan @Override 194b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public String toString() { 195b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan StringBuilder sb = new StringBuilder(); 196b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 197b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan final String country = this.mCountry; 198b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan final TimeZone tz = this.mTz; 199b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 200b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(mTzId); 201b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 202b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(tz.getDisplayName(false /* daylightTime */, TimeZone.LONG)); 203b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 204b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(tz.getDisplayName(false /* daylightTime */, TimeZone.SHORT)); 205b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 206b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (tz.useDaylightTime()) { 207b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(tz.getDisplayName(true, TimeZone.LONG)); 208b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 209b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(tz.getDisplayName(true, TimeZone.SHORT)); 210b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else { 211b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 212b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 213b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 214b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(tz.getRawOffset() / 3600000f); 215b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 216b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(tz.getDSTSavings() / 3600000f); 217b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 218b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(country); 219b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 220b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 221b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 1-1-2013 noon GMT 222b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(getLocalTime(1357041600000L)); 223b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 224b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 225b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 3-15-2013 noon GMT 226b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(getLocalTime(1363348800000L)); 227b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 228b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 229b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 7-1-2013 noon GMT 230b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(getLocalTime(1372680000000L)); 231b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 232b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 233b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // 11-01-2013 noon GMT 234b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(getLocalTime(1383307200000L)); 235b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append(SEPARATOR); 236b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 237b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan sb.append('\n'); 238b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return sb.toString(); 239b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 240b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 241b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan private static String formatTime(DateFormat df, int s) { 242b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan long ms = s * 1000L; 243b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return df.format(new Date(ms)); 244b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 245b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 246b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan /* 247b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * Returns a negative integer if this instance is less than the other; a 248b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * positive integer if this instance is greater than the other; 0 if this 249b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan * instance has the same order as the other. 250b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan */ 251b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan @Override 252b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan public int compareTo(TimeZoneInfo other) { 2531989c63ae3f98b5088e27564cd397ef5e8affaeaMichael Chan if (this.getNowOffsetMillis() != other.getNowOffsetMillis()) { 25409a2165919cb9b67c95b7885357c78e20bf5d9fbSam Blitzstein return (other.getNowOffsetMillis() < this.getNowOffsetMillis()) ? -1 : 1; 255b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 256b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 257b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // By country 258b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (this.mCountry == null) { 259b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (other.mCountry != null) { 260b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return 1; 261b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 262b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 263b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 264b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (other.mCountry == null) { 265b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return -1; 266b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } else { 267b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan int diff = this.mCountry.compareTo(other.mCountry); 268b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 269b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan if (diff != 0) { 270b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return diff; 271b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 272b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 273b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan 274b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan // Finally diff by display name 2755e905dfdd9c374ddf708d19062501038211356d2Michael Chan if (mDisplayName != null && other.mDisplayName != null) 2765e905dfdd9c374ddf708d19062501038211356d2Michael Chan return this.mDisplayName.compareTo(other.mDisplayName); 2775e905dfdd9c374ddf708d19062501038211356d2Michael Chan 278b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan return this.mTz.getDisplayName(Locale.getDefault()).compareTo( 279b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan other.mTz.getDisplayName(Locale.getDefault())); 2805e905dfdd9c374ddf708d19062501038211356d2Michael Chan 281b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan } 282b1b7080deea42aa533c3757b585cf765c6b76732Michael Chan} 283