TimeUtils.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.util;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.XmlResourceParser;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.luni.internal.util.ZoneInfoDB;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TimeZone;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Date;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.util.XmlUtils;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A class containing utility methods related to time zones.
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class TimeUtils {
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "TimeUtils";
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Tries to return a time zone that would have had the specified offset
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and DST value at the specified moment in the specified country.
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns null if no suitable zone could be found.
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static TimeZone getTimeZone(int offset, boolean dst, long when, String country) {
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (country == null) {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TimeZone best = null;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Resources r = Resources.getSystem();
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        XmlResourceParser parser = r.getXml(com.android.internal.R.xml.time_zones_by_country);
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Date d = new Date(when);
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TimeZone current = TimeZone.getDefault();
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String currentName = current.getID();
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int currentOffset = current.getOffset(when);
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean currentDst = current.inDaylightTime(d);
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            XmlUtils.beginDocument(parser, "timezones");
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (true) {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                XmlUtils.nextElement(parser);
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String element = parser.getName();
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (element == null || !(element.equals("timezone"))) {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String code = parser.getAttributeValue(null, "code");
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (country.equals(code)) {
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (parser.next() == XmlPullParser.TEXT) {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String maybe = parser.getText();
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // If the current time zone is from the right country
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // and meets the other known properties, keep it
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // instead of changing to another one.
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (maybe.equals(currentName)) {
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (currentOffset == offset && currentDst == dst) {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                return current;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Otherwise, take the first zone from the right
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // country that has the correct current offset and DST.
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // (Keep iterating instead of returning in case we
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // haven't encountered the current time zone yet.)
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (best == null) {
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            TimeZone tz = TimeZone.getTimeZone(maybe);
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (tz.getOffset(when) == offset &&
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                tz.inDaylightTime(d) == dst) {
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                best = tz;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (XmlPullParserException e) {
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Got exception while getting preferred time zone.", e);
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (IOException e) {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Got exception while getting preferred time zone.", e);
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parser.close();
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return best;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a String indicating the version of the time zone database currently
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in use.  The format of the string is dependent on the underlying time zone
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * database implementation, but will typically contain the year in which the database
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was updated plus a letter from a to z indicating changes made within that year.
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Time zone database updates should be expected to occur periodically due to
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * political and legal changes that cannot be anticipated in advance.  Therefore,
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when computing the UTC time for a future event, applications should be aware that
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the results may differ following a time zone database update.  This method allows
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * applications to detect that a database change has occurred, and to recalculate any
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cached times accordingly.
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The time zone database may be assumed to change only when the device runtime
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is restarted.  Therefore, it is not necessary to re-query the database version
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * during the lifetime of an activity.
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static String getTimeZoneDatabaseVersion() {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ZoneInfoDB.getVersion();
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
134