ZoneInfoDB.java revision 6cbefca623f55004ba65f11577fc25f92f6297dc
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License. 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 176d82ce5d35a5e84aedf08528fd98b849f3f565a6Elliott Hughespackage libcore.util; 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.RandomAccessFile; 213ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughesimport java.nio.ByteBuffer; 223ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughesimport java.nio.ByteOrder; 23d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughesimport java.nio.channels.FileChannel.MapMode; 24e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughesimport java.nio.charset.Charsets; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.TimeZone; 29d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughesimport libcore.io.BufferIterator; 309b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughesimport libcore.io.ErrnoException; 31f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughesimport libcore.io.IoUtils; 32d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughesimport libcore.io.MemoryMappedFile; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 346d82ce5d35a5e84aedf08528fd98b849f3f565a6Elliott Hughes// TODO: repackage this class, used by frameworks/base. 356d82ce5d35a5e84aedf08528fd98b849f3f565a6Elliott Hughesimport org.apache.harmony.luni.internal.util.TimezoneGetter; 366d82ce5d35a5e84aedf08528fd98b849f3f565a6Elliott Hughes 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 386cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes * A class used to initialize the time zone database. This implementation uses the 396cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes * Olson tzdata as the source of time zone information. However, to conserve 406cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes * disk space (inodes) and reduce I/O, all the data is concatenated into a single file, 416cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes * with an index to indicate the starting position of each time zone record. 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 436d82ce5d35a5e84aedf08528fd98b849f3f565a6Elliott Hughes * @hide - used to implement TimeZone 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic final class ZoneInfoDB { 46f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes private static final Object LOCK = new Object(); 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 483ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes /** 499b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes * Rather than open, read, and close the big data file each time we look up a time zone, 509b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes * we map the big data file during startup, and then just use the MemoryMappedFile. 519b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes * 529b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes * At the moment, this "big" data file is about 500 KiB. At some point, that will be small 539b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes * enough that we'll just keep the byte[] in memory. 549b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes */ 556cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes private static final MemoryMappedFile TZDATA = mapData(); 566cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes 576cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes private static String version; 589b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes 599b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes /** 603ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes * The 'ids' array contains time zone ids sorted alphabetically, for binary searching. 613ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes * The other two arrays are in the same order. 'byteOffsets' gives the byte offset 626cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes * of each time zone, and 'rawUtcOffsets' gives the time zone's raw UTC offset. 633ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes */ 643ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes private static String[] ids; 653ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes private static int[] byteOffsets; 663ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes private static int[] rawUtcOffsets; 676cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes 68f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes static { 696cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes readHeader(); 70f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes } 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 729b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes private ZoneInfoDB() { 739b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes } 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 756cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes private static void readHeader() { 766cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes // byte[12] tzdata_version -- "tzdata2012f\0" 776cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes // int file_format_version -- 1 786cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes // int index_offset 796cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes // int data_offset 806cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes // int zonetab_offset 816cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes BufferIterator it = TZDATA.bigEndianIterator(); 826cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes 836cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes byte[] tzdata_version = new byte[12]; 846cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes it.readByteArray(tzdata_version, 0, tzdata_version.length); 856cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes String magic = new String(tzdata_version, 0, 6, Charsets.US_ASCII); 866cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes if (!magic.equals("tzdata") || tzdata_version[11] != 0) { 876cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes throw new RuntimeException("bad tzdata magic: " + Arrays.toString(tzdata_version)); 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 896cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes version = new String(tzdata_version, 6, 5, Charsets.US_ASCII); 906cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes 916cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes int file_format_version = it.readInt(); 926cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes if (file_format_version != 1) { 936cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes throw new RuntimeException("unknown tzdata file format version: " + file_format_version); 946cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes } 956cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes 966cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes int index_offset = it.readInt(); 976cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes int data_offset = it.readInt(); 986cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes int zonetab_offset = it.readInt(); 996cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes if (zonetab_offset != 0) { 1006cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes throw new RuntimeException("non-zero zonetab offset: " + zonetab_offset); 1016cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes } 1026cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes 1036cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes readIndex(it, index_offset, data_offset); 104f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes } 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1069b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes private static MemoryMappedFile mapData() { 1079b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes try { 1086cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes String path = System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/tzdata"; 1096cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes return MemoryMappedFile.mmapRO(path); 1109b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes } catch (ErrnoException errnoException) { 1119b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes throw new AssertionError(errnoException); 1129b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes } 1139b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes } 1149b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes 1156cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes private static void readIndex(BufferIterator it, int indexOffset, int dataOffset) { 1166cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes it.seek(indexOffset); 117f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes 118bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes // The database reserves 40 bytes for each id. 119bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes final int SIZEOF_TZNAME = 40; 120bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes // The database uses 32-bit (4 byte) integers. 121bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes final int SIZEOF_TZINT = 4; 122f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes 123bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes byte[] idBytes = new byte[SIZEOF_TZNAME]; 1246cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes int indexSize = (dataOffset - indexOffset); 1256cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes int entryCount = indexSize / (SIZEOF_TZNAME + 3*SIZEOF_TZINT); 126f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes 1276cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes char[] idChars = new char[entryCount * SIZEOF_TZNAME]; 1286cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes int[] idEnd = new int[entryCount]; 129bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes int idOffset = 0; 130f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes 1316cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes byteOffsets = new int[entryCount]; 1326cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes rawUtcOffsets = new int[entryCount]; 133f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes 1346cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes for (int i = 0; i < entryCount; i++) { 135bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes it.readByteArray(idBytes, 0, idBytes.length); 1366cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes 137bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes byteOffsets[i] = it.readInt(); 1386cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes byteOffsets[i] += dataOffset; // TODO: change the file format so this is included. 1396cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes 140bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes int length = it.readInt(); 141bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes if (length < 44) { 142bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes throw new AssertionError("length in index file < sizeof(tzhead)"); 143f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes } 144bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes rawUtcOffsets[i] = it.readInt(); 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 146bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes // Don't include null chars in the String 147bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes int len = idBytes.length; 148bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes for (int j = 0; j < len; j++) { 149bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes if (idBytes[j] == 0) { 150bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes break; 151bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes } 152bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes idChars[idOffset++] = (char) (idBytes[j] & 0xFF); 153f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes } 154bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes 155bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes idEnd[i] = idOffset; 156bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes } 157bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes 158bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes // We create one string containing all the ids, and then break that into substrings. 159bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes // This way, all ids share a single char[] on the heap. 160bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes String allIds = new String(idChars, 0, idOffset); 1616cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes ids = new String[entryCount]; 1626cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes for (int i = 0; i < entryCount; i++) { 163bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes ids[i] = allIds.substring(i == 0 ? 0 : idEnd[i - 1], idEnd[i]); 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 16778c3de051d68b703af480778c100ca335690b250Elliott Hughes public static TimeZone makeTimeZone(String id) throws IOException { 1683ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes // Work out where in the big data file this time zone is. 1693ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes int index = Arrays.binarySearch(ids, id); 1703ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes if (index < 0) { 1713ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes return null; 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1746cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes BufferIterator data = TZDATA.bigEndianIterator(); 175d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes data.skip(byteOffsets[index]); 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1773ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes // Variable names beginning tzh_ correspond to those in "tzfile.h". 1783ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes // Check tzh_magic. 179d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes if (data.readInt() != 0x545a6966) { // "TZif" 1803ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes return null; 1813ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes } 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1833ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes // Skip the uninteresting part of the header. 184d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes data.skip(28); 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1863ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes // Read the sizes of the arrays we're about to read. 187d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes int tzh_timecnt = data.readInt(); 188d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes int tzh_typecnt = data.readInt(); 189d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes 190d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes data.skip(4); // Skip tzh_charcnt. 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1923ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes int[] transitions = new int[tzh_timecnt]; 193d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes data.readIntArray(transitions, 0, transitions.length); 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1953ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes byte[] type = new byte[tzh_timecnt]; 196d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes data.readByteArray(type, 0, type.length); 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1983ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes int[] gmtOffsets = new int[tzh_typecnt]; 1993ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes byte[] isDsts = new byte[tzh_typecnt]; 2003ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes for (int i = 0; i < tzh_typecnt; ++i) { 201d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes gmtOffsets[i] = data.readInt(); 202d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes isDsts[i] = data.readByte(); 203102b3a86bde04a4cffcbecd5b6d175d7790b132aElliott Hughes // We skip the abbreviation index. This would let us provide historically-accurate 204102b3a86bde04a4cffcbecd5b6d175d7790b132aElliott Hughes // time zone abbreviations (such as "AHST", "YST", and "AKST" for standard time in 205102b3a86bde04a4cffcbecd5b6d175d7790b132aElliott Hughes // America/Anchorage in 1982, 1983, and 1984 respectively). ICU only knows the current 206102b3a86bde04a4cffcbecd5b6d175d7790b132aElliott Hughes // names, though, so even if we did use this data to provide the correct abbreviations 207102b3a86bde04a4cffcbecd5b6d175d7790b132aElliott Hughes // for en_US, we wouldn't be able to provide correct abbreviations for other locales, 208102b3a86bde04a4cffcbecd5b6d175d7790b132aElliott Hughes // nor would we be able to provide correct long forms (such as "Yukon Standard Time") 209102b3a86bde04a4cffcbecd5b6d175d7790b132aElliott Hughes // for any locale. (The RI doesn't do any better than us here either.) 210102b3a86bde04a4cffcbecd5b6d175d7790b132aElliott Hughes data.skip(1); 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 213d6b9f2e0e9640ff9c896b394716cf5e7eee6e257Elliott Hughes return new ZoneInfo(id, transitions, type, gmtOffsets, isDsts); 2143ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes } 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2163ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes public static String[] getAvailableIDs() { 217866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes return ids.clone(); 2183ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes } 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2203ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes public static String[] getAvailableIDs(int rawOffset) { 2213ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes List<String> matches = new ArrayList<String>(); 2226cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes for (int i = 0, end = rawUtcOffsets.length; i < end; ++i) { 2233ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes if (rawUtcOffsets[i] == rawOffset) { 2243ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes matches.add(ids[i]); 2253ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes } 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2273ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes return matches.toArray(new String[matches.size()]); 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2303ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes public static TimeZone getSystemDefault() { 2313ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes synchronized (LOCK) { 2323ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes TimezoneGetter tzGetter = TimezoneGetter.getInstance(); 2333ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes String zoneName = tzGetter != null ? tzGetter.getId() : null; 2343ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes if (zoneName != null) { 2353ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes zoneName = zoneName.trim(); 2363ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes } 2373ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes if (zoneName == null || zoneName.isEmpty()) { 2383ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes // use localtime for the simulator 2393ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes // TODO: what does that correspond to? 2403ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes zoneName = "localtime"; 2413ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes } 2423ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes return TimeZone.getTimeZone(zoneName); 2433ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes } 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2463ab13ebe9d67b0b210865853902b854711ef45b0Elliott Hughes public static String getVersion() { 2476cbefca623f55004ba65f11577fc25f92f6297dcElliott Hughes return version; 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 250