1d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes/* 2d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * Copyright (C) 2007 The Android Open Source Project 3d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * 4d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * you may not use this file except in compliance with the License. 6d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * You may obtain a copy of the License at 7d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * 8d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * 10d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * Unless required by applicable law or agreed to in writing, software 11d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * See the License for the specific language governing permissions and 14d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * limitations under the License. 15d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes */ 16d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 17d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughesimport java.io.IOException; 18d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughesimport java.util.Arrays; 19d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughesimport java.util.Date; 20d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughesimport java.util.TimeZone; 21d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 22d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes/** 23d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * Copied from ZoneInfo and ZoneInfoDB in dalvik. 24d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes * {@hide} 25d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes */ 26d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughespublic class ZoneInfo extends TimeZone { 27d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 28d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private static final long MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000; 29d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private static final long MILLISECONDS_PER_400_YEARS = 30d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes MILLISECONDS_PER_DAY * (400 * 365 + 100 - 3); 31d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 32d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private static final long UNIX_OFFSET = 62167219200000L; 33d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 34d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private static final int[] NORMAL = new int[] { 35d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 36d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes }; 37d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 38d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private static final int[] LEAP = new int[] { 39d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 40d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes }; 41d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 42d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private static String nullName(byte[] data, int where, int off) { 43d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (off < 0) 44d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return null; 45d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 46d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int end = where + off; 47d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes while (end < data.length && data[end] != '\0') 48d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes end++; 49d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 50d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return new String(data, where + off, end - (where + off)); 51d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 52d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 53d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes public static ZoneInfo make(String name, byte[] data) { 54d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int ntransition = read4(data, 32); 55d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int ngmtoff = read4(data, 36); 56d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int base = 44; 57d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 58d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int[] transitions = new int[ntransition]; 59d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes for (int i = 0; i < ntransition; i++) 60d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes transitions[i] = read4(data, base + 4 * i); 61d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes base += 4 * ntransition; 62d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 63d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes byte[] type = new byte[ntransition]; 64d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes for (int i = 0; i < ntransition; i++) 65d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes type[i] = data[base + i]; 66d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes base += ntransition; 67d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 68d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int[] gmtoff = new int[ngmtoff]; 69d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes byte[] isdst = new byte[ngmtoff]; 70d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes byte[] abbrev = new byte[ngmtoff]; 71d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes for (int i = 0; i < ngmtoff; i++) { 72d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes gmtoff[i] = read4(data, base + 6 * i); 73d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes isdst[i] = data[base + 6 * i + 4]; 74d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes abbrev[i] = data[base + 6 * i + 5]; 75d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 76d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 77d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes base += 6 * ngmtoff; 78d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 79d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return new ZoneInfo(name, transitions, type, gmtoff, isdst, abbrev, data, base); 80d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 81d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 82d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private static int read4(byte[] data, int off) { 83d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return ((data[off ] & 0xFF) << 24) | 84d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes ((data[off + 1] & 0xFF) << 16) | 85d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes ((data[off + 2] & 0xFF) << 8) | 86d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes ((data[off + 3] & 0xFF) << 0); 87d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 88d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 89d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes /*package*/ ZoneInfo(String name, int[] transitions, byte[] type, 90d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int[] gmtoff, byte[] isdst, byte[] abbrev, 91d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes byte[] data, int abbrevoff) { 92d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mTransitions = transitions; 93d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mTypes = type; 94d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mGmtOffs = gmtoff; 95d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mIsDsts = isdst; 96d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mUseDst = false; 97d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes setID(name); 98d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 99d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes // Find the latest GMT and non-GMT offsets for their abbreviations 100d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 101d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int lastdst; 102d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes for (lastdst = mTransitions.length - 1; lastdst >= 0; lastdst--) { 103d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (mIsDsts[mTypes[lastdst] & 0xFF] != 0) 104d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes break; 105d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 106d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 107d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int laststd; 108d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes for (laststd = mTransitions.length - 1; laststd >= 0; laststd--) { 109d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (mIsDsts[mTypes[laststd] & 0xFF] == 0) 110d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes break; 111d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 112d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 113d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (lastdst >= 0) { 114d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mDaylightName = nullName(data, abbrevoff, 115d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes abbrev[mTypes[lastdst] & 0xFF]); 116d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 117d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (laststd >= 0) { 118d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mStandardName = nullName(data, abbrevoff, 119d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes abbrev[mTypes[laststd] & 0xFF]); 120d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 121d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 122d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes // Use the latest non-DST offset if any as the raw offset 123d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 124d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (laststd < 0) { 125d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes laststd = 0; 126d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 127d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 128d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (laststd >= mTypes.length) { 129d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mRawOffset = mGmtOffs[0]; 130d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } else { 131d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mRawOffset = mGmtOffs[mTypes[laststd] & 0xFF]; 132d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 133d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 134d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes // Subtract the raw offset from all offsets so it can be changed 135d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes // and affect them too. 136d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes // Find whether there exist any observances of DST. 137d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 138d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes for (int i = 0; i < mGmtOffs.length; i++) { 139d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mGmtOffs[i] -= mRawOffset; 140d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 141d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (mIsDsts[i] != 0) { 142d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mUseDst = true; 143d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 144d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 145d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 146d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mRawOffset *= 1000; 147d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 148d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 149d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes @Override 150d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes public int getOffset(@SuppressWarnings("unused") int era, 151d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int year, int month, int day, 152d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes @SuppressWarnings("unused") int dayOfWeek, 153d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int millis) { 154d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes // XXX This assumes Gregorian always; Calendar switches from 155d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes // Julian to Gregorian in 1582. What calendar system are the 156d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes // arguments supposed to come from? 157d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 158d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes long calc = (year / 400) * MILLISECONDS_PER_400_YEARS; 159d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes year %= 400; 160d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 161d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes calc += year * (365 * MILLISECONDS_PER_DAY); 162d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes calc += ((year + 3) / 4) * MILLISECONDS_PER_DAY; 163d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 164d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (year > 0) 165d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes calc -= ((year - 1) / 100) * MILLISECONDS_PER_DAY; 166d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 167d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes boolean isLeap = (year == 0 || (year % 4 == 0 && year % 100 != 0)); 168d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int[] mlen = isLeap ? LEAP : NORMAL; 169d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 170d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes calc += mlen[month] * MILLISECONDS_PER_DAY; 171d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes calc += (day - 1) * MILLISECONDS_PER_DAY; 172d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes calc += millis; 173d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 174d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes calc -= mRawOffset; 175d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes calc -= UNIX_OFFSET; 176d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 177d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return getOffset(calc); 178d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 179d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 180d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes @Override 181d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes public int getOffset(long when) { 182d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int unix = (int) (when / 1000); 183d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int trans = Arrays.binarySearch(mTransitions, unix); 184d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 185d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (trans == ~0) { 186d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return mGmtOffs[0] * 1000 + mRawOffset; 187d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 188d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (trans < 0) { 189d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes trans = ~trans - 1; 190d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 191d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 192d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return mGmtOffs[mTypes[trans] & 0xFF] * 1000 + mRawOffset; 193d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 194d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 195d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes @Override 196d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes public int getRawOffset() { 197d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return mRawOffset; 198d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 199d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 200d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes @Override 201d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes public void setRawOffset(int off) { 202d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mRawOffset = off; 203d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 204d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 205d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes @Override 206d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes public boolean inDaylightTime(Date when) { 207d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int unix = (int) (when.getTime() / 1000); 208d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int trans = Arrays.binarySearch(mTransitions, unix); 209d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 210d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (trans == ~0) { 211d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return mIsDsts[0] != 0; 212d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 213d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (trans < 0) { 214d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes trans = ~trans - 1; 215d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 216d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 217d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return mIsDsts[mTypes[trans] & 0xFF] != 0; 218d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 219d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 220d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes @Override 221d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes public boolean useDaylightTime() { 222d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return mUseDst; 223d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 224d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 225d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private int mRawOffset; 226d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private int[] mTransitions; 227d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private int[] mGmtOffs; 228d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private byte[] mTypes; 229d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private byte[] mIsDsts; 230d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private boolean mUseDst; 231d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private String mDaylightName; 232d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes private String mStandardName; 233d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 234d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes @Override 235d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes public boolean equals(Object obj) { 236d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (this == obj) { 237d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return true; 238d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 239d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes if (!(obj instanceof ZoneInfo)) { 240d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return false; 241d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 242d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes ZoneInfo other = (ZoneInfo) obj; 243d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return mUseDst == other.mUseDst 244d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes && (mDaylightName == null ? other.mDaylightName == null : 245d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mDaylightName.equals(other.mDaylightName)) 246d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes && (mStandardName == null ? other.mStandardName == null : 247d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mStandardName.equals(other.mStandardName)) 248d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes && mRawOffset == other.mRawOffset 249d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes // Arrays.equals returns true if both arrays are null 250d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes && Arrays.equals(mGmtOffs, other.mGmtOffs) 251d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes && Arrays.equals(mIsDsts, other.mIsDsts) 252d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes && Arrays.equals(mTypes, other.mTypes) 253d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes && Arrays.equals(mTransitions, other.mTransitions); 254d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 255d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes 256d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes @Override 257d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes public int hashCode() { 258d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes final int prime = 31; 259d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes int result = 1; 260d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes result = prime * result + ((mDaylightName == null) ? 0 : 261d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mDaylightName.hashCode()); 262d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes result = prime * result + Arrays.hashCode(mGmtOffs); 263d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes result = prime * result + Arrays.hashCode(mIsDsts); 264d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes result = prime * result + mRawOffset; 265d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes result = prime * result + ((mStandardName == null) ? 0 : 266d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes mStandardName.hashCode()); 267d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes result = prime * result + Arrays.hashCode(mTransitions); 268d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes result = prime * result + Arrays.hashCode(mTypes); 269d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes result = prime * result + (mUseDst ? 1231 : 1237); 270d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes return result; 271d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes } 272d40e63ee47e4a7f072a9d9a20e09c26f0090b02cElliott Hughes} 273