TimeUtils.java revision f013e1afd1e68af5e3b868c26a653bbfb39538f8
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.util;
18
19import android.content.res.Resources;
20import android.content.res.XmlResourceParser;
21
22import org.apache.harmony.luni.internal.util.ZoneInfoDB;
23import org.xmlpull.v1.XmlPullParser;
24import org.xmlpull.v1.XmlPullParserException;
25
26import java.io.IOException;
27import java.util.TimeZone;
28import java.util.Date;
29
30import com.android.internal.util.XmlUtils;
31
32/**
33 * A class containing utility methods related to time zones.
34 */
35public class TimeUtils {
36    private static final String TAG = "TimeUtils";
37
38    /**
39     * Tries to return a time zone that would have had the specified offset
40     * and DST value at the specified moment in the specified country.
41     * Returns null if no suitable zone could be found.
42     */
43    public static TimeZone getTimeZone(int offset, boolean dst, long when, String country) {
44        if (country == null) {
45            return null;
46        }
47
48        TimeZone best = null;
49
50        Resources r = Resources.getSystem();
51        XmlResourceParser parser = r.getXml(com.android.internal.R.xml.time_zones_by_country);
52        Date d = new Date(when);
53
54        TimeZone current = TimeZone.getDefault();
55        String currentName = current.getID();
56        int currentOffset = current.getOffset(when);
57        boolean currentDst = current.inDaylightTime(d);
58
59        try {
60            XmlUtils.beginDocument(parser, "timezones");
61
62            while (true) {
63                XmlUtils.nextElement(parser);
64
65                String element = parser.getName();
66                if (element == null || !(element.equals("timezone"))) {
67                    break;
68                }
69
70                String code = parser.getAttributeValue(null, "code");
71
72                if (country.equals(code)) {
73                    if (parser.next() == XmlPullParser.TEXT) {
74                        String maybe = parser.getText();
75
76                        // If the current time zone is from the right country
77                        // and meets the other known properties, keep it
78                        // instead of changing to another one.
79
80                        if (maybe.equals(currentName)) {
81                            if (currentOffset == offset && currentDst == dst) {
82                                return current;
83                            }
84                        }
85
86                        // Otherwise, take the first zone from the right
87                        // country that has the correct current offset and DST.
88                        // (Keep iterating instead of returning in case we
89                        // haven't encountered the current time zone yet.)
90
91                        if (best == null) {
92                            TimeZone tz = TimeZone.getTimeZone(maybe);
93
94                            if (tz.getOffset(when) == offset &&
95                                tz.inDaylightTime(d) == dst) {
96                                best = tz;
97                            }
98                        }
99                    }
100                }
101            }
102        } catch (XmlPullParserException e) {
103            Log.e(TAG, "Got exception while getting preferred time zone.", e);
104        } catch (IOException e) {
105            Log.e(TAG, "Got exception while getting preferred time zone.", e);
106        } finally {
107            parser.close();
108        }
109
110        return best;
111    }
112
113    /**
114     * Returns a String indicating the version of the time zone database currently
115     * in use.  The format of the string is dependent on the underlying time zone
116     * database implementation, but will typically contain the year in which the database
117     * was updated plus a letter from a to z indicating changes made within that year.
118     *
119     * <p>Time zone database updates should be expected to occur periodically due to
120     * political and legal changes that cannot be anticipated in advance.  Therefore,
121     * when computing the UTC time for a future event, applications should be aware that
122     * the results may differ following a time zone database update.  This method allows
123     * applications to detect that a database change has occurred, and to recalculate any
124     * cached times accordingly.
125     *
126     * <p>The time zone database may be assumed to change only when the device runtime
127     * is restarted.  Therefore, it is not necessary to re-query the database version
128     * during the lifetime of an activity.
129     */
130    public static String getTimeZoneDatabaseVersion() {
131        return ZoneInfoDB.getVersion();
132    }
133}
134