1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2078c3de051d68b703af480778c100ca335690b250Elliott Hughesimport java.io.IOException;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable;
2291348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughesimport java.util.regex.Matcher;
2391348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughesimport java.util.regex.Pattern;
2421557bb6a8f35a2f9889adba449cac950c9d41b9Elliott Hughesimport libcore.icu.TimeZones;
256d82ce5d35a5e84aedf08528fd98b849f3f565a6Elliott Hughesimport libcore.util.ZoneInfoDB;
26f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
28f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * {@code TimeZone} represents a time zone, primarily used for configuring a {@link Calendar} or
29705462a2b003b2eeed90bf3cebe0871e02554cbdElliott Hughes * {@link java.text.SimpleDateFormat} instance.
30f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
31f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * <p>Most applications will use {@link #getDefault} which returns a {@code TimeZone} based on
32f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * the time zone where the program is running.
33f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
3491348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes * <p>You can also get a specific {@code TimeZone} {@link #getTimeZone by Olson ID}.
35f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
36f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * <p>It is highly unlikely you'll ever want to use anything but the factory methods yourself.
37705462a2b003b2eeed90bf3cebe0871e02554cbdElliott Hughes * Let classes like {@link Calendar} and {@link java.text.SimpleDateFormat} do the date
38705462a2b003b2eeed90bf3cebe0871e02554cbdElliott Hughes * computations for you.
39f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
40f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * <p>If you do need to do date computations manually, there are two common cases to take into
41f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * account:
42f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * <ul>
43f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * <li>Somewhere like California, where daylight time is used.
44f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * The {@link #useDaylightTime} method will always return true, and {@link #inDaylightTime}
45f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * must be used to determine whether or not daylight time applies to a given {@code Date}.
46f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * The {@link #getRawOffset} method will return a raw offset of (in this case) -8 hours from UTC,
47f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * which isn't usually very useful. More usefully, the {@link #getOffset} methods return the
48f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * actual offset from UTC <i>for a given point in time</i>; this is the raw offset plus (if the
49f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * point in time is {@link #inDaylightTime in daylight time}) the applicable
50f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * {@link #getDSTSavings DST savings} (usually, but not necessarily, 1 hour).
51f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * <li>Somewhere like Japan, where daylight time is not used.
52f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * The {@link #useDaylightTime} and {@link #inDaylightTime} methods both always return false,
53f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * and the raw and actual offsets will always be the same.
54f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * </ul>
55f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes *
56f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * <p>Note the type returned by the factory methods {@link #getDefault} and {@link #getTimeZone} is
57f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * implementation dependent. This may introduce serialization incompatibility issues between
58f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * different implementations. Android returns instances of {@link SimpleTimeZone} so that
59f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * the bytes serialized by Android can be deserialized successfully on other
60f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * implementations, but the reverse compatibility cannot be guaranteed.
61f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
62f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * @see Calendar
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see GregorianCalendar
64f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes * @see SimpleDateFormat
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see SimpleTimeZone
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class TimeZone implements Serializable, Cloneable {
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = 3581463369166924961L;
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
7091348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes    private static final Pattern CUSTOM_ZONE_ID_PATTERN = Pattern.compile("^GMT[-+](\\d{1,2})(:?(\\d\\d))?$");
7191348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
732f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * The short display name style, such as {@code PDT}. Requests for this
742f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * style may yield GMT offsets like {@code GMT-08:00}.
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int SHORT = 0;
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
792f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * The long display name style, such as {@code Pacific Daylight Time}.
802f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Requests for this style may yield GMT offsets like {@code GMT-08:00}.
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final int LONG = 1;
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
8478c3de051d68b703af480778c100ca335690b250Elliott Hughes    private static final TimeZone GMT = new SimpleTimeZone(0, "GMT");
8578c3de051d68b703af480778c100ca335690b250Elliott Hughes    private static final TimeZone UTC = new SimpleTimeZone(0, "UTC");
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
872f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    private static TimeZone defaultTimeZone;
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String ID;
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
912f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    public TimeZone() {}
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
942f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Returns a new time zone with the same ID, raw offset, and daylight
952f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * savings time rules as this time zone.
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
972f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    @Override public Object clone() {
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
992f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson            return super.clone();
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (CloneNotSupportedException e) {
1012f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson            throw new AssertionError(e);
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1062f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Returns the system's installed time zone IDs. Any of these IDs can be
1072f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * passed to {@link #getTimeZone} to lookup the corresponding time zone
1082f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * instance.
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static synchronized String[] getAvailableIDs() {
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ZoneInfoDB.getAvailableIDs();
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1152f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Returns the IDs of the time zones whose offset from UTC is {@code
1162f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * offsetMillis}. Any of these IDs can be passed to {@link #getTimeZone} to
1172f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * lookup the corresponding time zone instance.
118f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1192f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * @return a possibly-empty array.
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1212f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    public static synchronized String[] getAvailableIDs(int offsetMillis) {
1222f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        return ZoneInfoDB.getAvailableIDs(offsetMillis);
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1262f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Returns the user's preferred time zone. This may have been overridden for
1272f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * this process with {@link #setDefault}.
128f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1292f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * <p>Since the user's time zone changes dynamically, avoid caching this
1302f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * value. Instead, use this method to look it up for each use.
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static synchronized TimeZone getDefault() {
1332f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        if (defaultTimeZone == null) {
1342f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson            defaultTimeZone = ZoneInfoDB.getSystemDefault();
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1362f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        return (TimeZone) defaultTimeZone.clone();
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1402f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Equivalent to {@code getDisplayName(false, TimeZone.LONG, Locale.getDefault())}.
1412f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * <a href="../util/Locale.html#default_locale">Be wary of the default locale</a>.
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final String getDisplayName() {
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getDisplayName(false, LONG, Locale.getDefault());
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1482f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Equivalent to {@code getDisplayName(false, TimeZone.LONG, locale)}.
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final String getDisplayName(Locale locale) {
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getDisplayName(false, LONG, locale);
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1552f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Equivalent to {@code getDisplayName(daylightTime, style, Locale.getDefault())}.
1562f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * <a href="../util/Locale.html#default_locale">Be wary of the default locale</a>.
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final String getDisplayName(boolean daylightTime, int style) {
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getDisplayName(daylightTime, style, Locale.getDefault());
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1632f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Returns the {@link #SHORT short} or {@link #LONG long} name of this time
1642f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * zone with either standard or daylight time, as written in {@code locale}.
1652f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * If the name is not available, the result is in the format
1662f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * {@code GMT[+-]hh:mm}.
167f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1682f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * @param daylightTime true for daylight time, false for standard time.
1692f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * @param style either {@link TimeZone#LONG} or {@link TimeZone#SHORT}.
1702f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * @param locale the display locale.
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getDisplayName(boolean daylightTime, int style, Locale locale) {
1732f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        if (style != SHORT && style != LONG) {
1742f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson            throw new IllegalArgumentException();
1752f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        }
176f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
1772f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        boolean useDaylight = daylightTime && useDaylightTime();
1782f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson
179566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes        String[][] zoneStrings = TimeZones.getZoneStrings(locale);
180566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes        String result = TimeZones.getDisplayName(zoneStrings, getID(), daylightTime, style);
1812f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        if (result != null) {
1822f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson            return result;
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1842f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson
185566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes        // TODO: do we ever get here?
186566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes
1872f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        int offset = getRawOffset();
1882f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        if (useDaylight && this instanceof SimpleTimeZone) {
1892f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson            offset += getDSTSavings();
1902f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        }
1912f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        offset /= 60000;
1922f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        char sign = '+';
1932f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        if (offset < 0) {
1942f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson            sign = '-';
1952f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson            offset = -offset;
1962f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        }
1972f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        StringBuilder builder = new StringBuilder(9);
1982f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        builder.append("GMT");
1992f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        builder.append(sign);
2002f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        appendNumber(builder, 2, offset / 60);
2012f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        builder.append(':');
2022f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        appendNumber(builder, 2, offset % 60);
2032f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        return builder.toString();
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2062f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    private void appendNumber(StringBuilder builder, int count, int value) {
207f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        String string = Integer.toString(value);
2082f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        for (int i = 0; i < count - string.length(); i++) {
2092f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson            builder.append('0');
210f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
2112f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        builder.append(string);
212f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    }
213f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2152f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Returns the ID of this {@code TimeZone}, such as
2162f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * {@code America/Los_Angeles}, {@code GMT-08:00} or {@code UTC}.
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getID() {
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ID;
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
22378c3de051d68b703af480778c100ca335690b250Elliott Hughes     * Returns the latest daylight savings in milliseconds for this time zone, relative
22478c3de051d68b703af480778c100ca335690b250Elliott Hughes     * to this time zone's regular UTC offset (as returned by {@link #getRawOffset}).
225f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
22678c3de051d68b703af480778c100ca335690b250Elliott Hughes     * <p>This class returns {@code 3600000} (1 hour) for time zones
22778c3de051d68b703af480778c100ca335690b250Elliott Hughes     * that use daylight savings time and {@code 0} for timezones that do not,
22878c3de051d68b703af480778c100ca335690b250Elliott Hughes     * leaving it to subclasses to override this method for other daylight savings
22978c3de051d68b703af480778c100ca335690b250Elliott Hughes     * offsets. (There are time zones, such as {@code Australia/Lord_Howe},
23078c3de051d68b703af480778c100ca335690b250Elliott Hughes     * that use other values.)
23178c3de051d68b703af480778c100ca335690b250Elliott Hughes     *
23278c3de051d68b703af480778c100ca335690b250Elliott Hughes     * <p>Note that this method doesn't tell you whether or not to <i>apply</i> the
2332f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * offset: you need to call {@code inDaylightTime} for the specific time
2342f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * you're interested in. If this method returns a non-zero offset, that only
2352f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * tells you that this {@code TimeZone} sometimes observes daylight savings.
23678c3de051d68b703af480778c100ca335690b250Elliott Hughes     *
23778c3de051d68b703af480778c100ca335690b250Elliott Hughes     * <p>Note also that this method doesn't necessarily return the value you need
23878c3de051d68b703af480778c100ca335690b250Elliott Hughes     * to apply to the time you're working with. This value can and does change over
23978c3de051d68b703af480778c100ca335690b250Elliott Hughes     * time for a given time zone.
24078c3de051d68b703af480778c100ca335690b250Elliott Hughes     *
24178c3de051d68b703af480778c100ca335690b250Elliott Hughes     * <p>It's highly unlikely that you should ever call this method. You
24278c3de051d68b703af480778c100ca335690b250Elliott Hughes     * probably want {@link #getOffset} instead, which tells you the offset
24378c3de051d68b703af480778c100ca335690b250Elliott Hughes     * for a specific point in time, and takes daylight savings into account for you.
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getDSTSavings() {
2462f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        return useDaylightTime() ? 3600000 : 0;
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2502f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Returns the offset in milliseconds from UTC for this time zone at {@code
2512f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * time}. The offset includes daylight savings time if the specified
2522f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * date is within the daylight savings time period.
253f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2542f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * @param time the date in milliseconds since January 1, 1970 00:00:00 UTC
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getOffset(long time) {
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (inDaylightTime(new Date(time))) {
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return getRawOffset() + getDSTSavings();
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getRawOffset();
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2642f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Returns this time zone's offset in milliseconds from UTC at the specified
2652f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * date and time. The offset includes daylight savings time if the date
2662f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * and time is within the daylight savings time period.
267f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2682f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * <p>This method is intended to be used by {@link Calendar} to compute
2692f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * {@link Calendar#DST_OFFSET} and {@link Calendar#ZONE_OFFSET}. Application
2702f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * code should have no reason to call this method directly. Each parameter
2712f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * is interpreted in the same way as the corresponding {@code Calendar}
2722f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * field. Refer to {@link Calendar} for specific definitions of this
2732f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * method's parameters.
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2752f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    public abstract int getOffset(int era, int year, int month, int day,
2762f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson            int dayOfWeek, int timeOfDayMillis);
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2792f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Returns the offset in milliseconds from UTC of this time zone's standard
2802f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * time.
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2822f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    public abstract int getRawOffset();
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
285eeddfe47f90ce73199e57c10d6caa3c1a05dbed3Jean-Baptiste Queru     * Returns a {@code TimeZone} corresponding to the given {@code id}, or {@code GMT}
286eeddfe47f90ce73199e57c10d6caa3c1a05dbed3Jean-Baptiste Queru     * for unknown ids.
287f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes     *
28891348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes     * <p>An ID can be an Olson name of the form <i>Area</i>/<i>Location</i>, such
289f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes     * as {@code America/Los_Angeles}. The {@link #getAvailableIDs} method returns
290f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes     * the supported names.
291f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes     *
29291348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes     * <p>This method can also create a custom {@code TimeZone} given an ID with the following
29391348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes     * syntax: {@code GMT[+|-]hh[[:]mm]}. For example, {@code "GMT+05:00"}, {@code "GMT+0500"},
29491348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes     * {@code "GMT+5:00"}, {@code "GMT+500"}, {@code "GMT+05"}, and {@code "GMT+5"} all return
29591348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes     * an object with a raw offset of +5 hours from UTC, and which does <i>not</i> use daylight
29691348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes     * savings. These are rarely useful, because they don't correspond to time zones actually
29791348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes     * in use by humans.
298f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2996c0aa9e00fdbcc2765d3c498c45e078457944468Elliott Hughes     * <p>Other than the special cases "UTC" and "GMT" (which are synonymous in this context,
3006c0aa9e00fdbcc2765d3c498c45e078457944468Elliott Hughes     * both corresponding to UTC), Android does not support the deprecated three-letter time
3016c0aa9e00fdbcc2765d3c498c45e078457944468Elliott Hughes     * zone IDs used in Java 1.1.
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3032f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    public static synchronized TimeZone getTimeZone(String id) {
3046fb123c8681a795c65cbd67ffcc0ef641c473288Elliott Hughes        if (id == null) {
3056fb123c8681a795c65cbd67ffcc0ef641c473288Elliott Hughes            throw new NullPointerException("id == null");
3066fb123c8681a795c65cbd67ffcc0ef641c473288Elliott Hughes        }
30778c3de051d68b703af480778c100ca335690b250Elliott Hughes
30878c3de051d68b703af480778c100ca335690b250Elliott Hughes        // Special cases? These can clone an existing instance.
30978c3de051d68b703af480778c100ca335690b250Elliott Hughes        // TODO: should we just add a cache to ZoneInfoDB instead?
31078c3de051d68b703af480778c100ca335690b250Elliott Hughes        if (id.length() == 3) {
31178c3de051d68b703af480778c100ca335690b250Elliott Hughes            if (id.equals("GMT")) {
31278c3de051d68b703af480778c100ca335690b250Elliott Hughes                return (TimeZone) GMT.clone();
31378c3de051d68b703af480778c100ca335690b250Elliott Hughes            }
31478c3de051d68b703af480778c100ca335690b250Elliott Hughes            if (id.equals("UTC")) {
31578c3de051d68b703af480778c100ca335690b250Elliott Hughes                return (TimeZone) UTC.clone();
31678c3de051d68b703af480778c100ca335690b250Elliott Hughes            }
31778c3de051d68b703af480778c100ca335690b250Elliott Hughes        }
31878c3de051d68b703af480778c100ca335690b250Elliott Hughes
31978c3de051d68b703af480778c100ca335690b250Elliott Hughes        // In the database?
32078c3de051d68b703af480778c100ca335690b250Elliott Hughes        TimeZone zone = null;
32178c3de051d68b703af480778c100ca335690b250Elliott Hughes        try {
32278c3de051d68b703af480778c100ca335690b250Elliott Hughes            zone = ZoneInfoDB.makeTimeZone(id);
32378c3de051d68b703af480778c100ca335690b250Elliott Hughes        } catch (IOException ignored) {
3242f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        }
32578c3de051d68b703af480778c100ca335690b250Elliott Hughes
32678c3de051d68b703af480778c100ca335690b250Elliott Hughes        // Custom time zone?
327f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes        if (zone == null && id.length() > 3 && id.startsWith("GMT")) {
328f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes            zone = getCustomTimeZone(id);
329f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes        }
33078c3de051d68b703af480778c100ca335690b250Elliott Hughes
33178c3de051d68b703af480778c100ca335690b250Elliott Hughes        // We never return null; on failure we return the equivalent of "GMT".
33278c3de051d68b703af480778c100ca335690b250Elliott Hughes        return (zone != null) ? zone : (TimeZone) GMT.clone();
333f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes    }
334f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes
335f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes    /**
33691348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes     * Returns a new SimpleTimeZone for an ID of the form "GMT[+|-]hh[[:]mm]", or null.
337f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes     */
338f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes    private static TimeZone getCustomTimeZone(String id) {
33991348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        Matcher m = CUSTOM_ZONE_ID_PATTERN.matcher(id);
34091348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        if (!m.matches()) {
341f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes            return null;
3422f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        }
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
34491348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        int hour;
34591348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        int minute = 0;
34691348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        try {
34791348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes            hour = Integer.parseInt(m.group(1));
34891348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes            if (m.group(3) != null) {
34991348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes                minute = Integer.parseInt(m.group(3));
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
35191348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        } catch (NumberFormatException impossible) {
35291348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes            throw new AssertionError(impossible);
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
35591348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
35691348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes            return null;
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
35991348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        char sign = id.charAt(3);
36091348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        int raw = (hour * 3600000) + (minute * 60000);
36191348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        if (sign == '-') {
36291348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes            raw = -raw;
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36591348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        String cleanId = String.format("GMT%c%02d:%02d", sign, hour, minute);
36691348f798cddae22b59ee1a17bd24315c0897f6fElliott Hughes        return new SimpleTimeZone(raw, cleanId);
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3702f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Returns true if {@code timeZone} has the same rules as this time zone.
371f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
3722f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * <p>The base implementation returns true if both time zones have the same
3732f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * raw offset.
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3752f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    public boolean hasSameRules(TimeZone timeZone) {
3762f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        if (timeZone == null) {
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
3792f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        return getRawOffset() == timeZone.getRawOffset();
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3832f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Returns true if {@code time} is in a daylight savings time period for
3842f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * this time zone.
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3862f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    public abstract boolean inDaylightTime(Date time);
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3892f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Overrides the default time zone for the current process only.
390f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
3912f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * <p><strong>Warning</strong>: avoid using this method to use a custom time
3922f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * zone in your process. This value may be cleared or overwritten at any
3932f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * time, which can cause unexpected behavior. Instead, manually supply a
3942f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * custom time zone as needed.
3952f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     *
3962f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * @param timeZone a custom time zone, or {@code null} to set the default to
3972f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     *     the user's preferred value.
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3992f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    public static synchronized void setDefault(TimeZone timeZone) {
4002f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        defaultTimeZone = timeZone != null ? (TimeZone) timeZone.clone() : null;
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the ID of this {@code TimeZone}.
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4062f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    public void setID(String id) {
4072f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        if (id == null) {
40886acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("id == null");
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
4102f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson        ID = id;
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4142f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * Sets the offset in milliseconds from UTC of this time zone's standard
4152f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     * time.
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4172f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    public abstract void setRawOffset(int offsetMillis);
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
420d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     * Returns true if this time zone has a future transition to or from
421d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     * daylight savings time.
4222f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson     *
423d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     * <p><strong>Warning:</strong> this returns false for time zones like
424d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     * {@code Asia/Kuala_Lumpur} that have previously used DST but do not
425d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     * currently. A hypothetical country that has never observed daylight
426d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     * savings before but plans to start next year would return true.
427d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     *
428d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     * <p><strong>Warning:</strong> this returns true for time zones that use
429d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     * DST, even when it is not active.
430d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     *
431d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     * <p>Use {@link #inDaylightTime} to find out whether daylight savings is
432d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     * in effect at a specific time.
433d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     *
434d8d3329347af700beed67172c77046b5c2ecece2Jesse Wilson     * <p>Most applications should not use this method.
435f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     */
4362f633269e71f3fb0b6248cc695cf37c5cbaf7e60Jesse Wilson    public abstract boolean useDaylightTime();
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
438