TimeUtils.java revision b5e3165129a5871cf679a67d9e9323ffad3d4902
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;
271ebccf531d1049853b3b0630035434619682c016Dianne Hackbornimport java.io.PrintWriter;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TimeZone;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Date;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
312269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.util.XmlUtils;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A class containing utility methods related to time zones.
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class TimeUtils {
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "TimeUtils";
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Tries to return a time zone that would have had the specified offset
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and DST value at the specified moment in the specified country.
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns null if no suitable zone could be found.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static TimeZone getTimeZone(int offset, boolean dst, long when, String country) {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (country == null) {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TimeZone best = null;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Resources r = Resources.getSystem();
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        XmlResourceParser parser = r.getXml(com.android.internal.R.xml.time_zones_by_country);
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Date d = new Date(when);
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TimeZone current = TimeZone.getDefault();
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String currentName = current.getID();
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int currentOffset = current.getOffset(when);
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean currentDst = current.inDaylightTime(d);
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            XmlUtils.beginDocument(parser, "timezones");
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (true) {
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                XmlUtils.nextElement(parser);
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String element = parser.getName();
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (element == null || !(element.equals("timezone"))) {
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String code = parser.getAttributeValue(null, "code");
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (country.equals(code)) {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (parser.next() == XmlPullParser.TEXT) {
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String maybe = parser.getText();
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // If the current time zone is from the right country
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // and meets the other known properties, keep it
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // instead of changing to another one.
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (maybe.equals(currentName)) {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (currentOffset == offset && currentDst == dst) {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                return current;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Otherwise, take the first zone from the right
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // country that has the correct current offset and DST.
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // (Keep iterating instead of returning in case we
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // haven't encountered the current time zone yet.)
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (best == null) {
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            TimeZone tz = TimeZone.getTimeZone(maybe);
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (tz.getOffset(when) == offset &&
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                tz.inDaylightTime(d) == dst) {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                best = tz;
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            }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (XmlPullParserException e) {
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Got exception while getting preferred time zone.", e);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (IOException e) {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Got exception while getting preferred time zone.", e);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parser.close();
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return best;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a String indicating the version of the time zone database currently
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in use.  The format of the string is dependent on the underlying time zone
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * database implementation, but will typically contain the year in which the database
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was updated plus a letter from a to z indicating changes made within that year.
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Time zone database updates should be expected to occur periodically due to
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * political and legal changes that cannot be anticipated in advance.  Therefore,
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when computing the UTC time for a future event, applications should be aware that
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the results may differ following a time zone database update.  This method allows
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * applications to detect that a database change has occurred, and to recalculate any
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cached times accordingly.
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The time zone database may be assumed to change only when the device runtime
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is restarted.  Therefore, it is not necessary to re-query the database version
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * during the lifetime of an activity.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static String getTimeZoneDatabaseVersion() {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ZoneInfoDB.getVersion();
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1341ebccf531d1049853b3b0630035434619682c016Dianne Hackborn
135b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    /** @hide Field length that can hold 999 days of time */
136b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    public static final int HUNDRED_DAY_FIELD_LEN = 19;
137b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
1381ebccf531d1049853b3b0630035434619682c016Dianne Hackborn    private static final int SECONDS_PER_MINUTE = 60;
1391ebccf531d1049853b3b0630035434619682c016Dianne Hackborn    private static final int SECONDS_PER_HOUR = 60 * 60;
1401ebccf531d1049853b3b0630035434619682c016Dianne Hackborn    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
1411ebccf531d1049853b3b0630035434619682c016Dianne Hackborn
142b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    private static final Object sFormatSync = new Object();
143b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    private static char[] sFormatStr = new char[HUNDRED_DAY_FIELD_LEN+5];
144b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
145b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    static private int accumField(int amt, int suffix, boolean always, int zeropad) {
146b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        if (amt > 99 || (always && zeropad >= 3)) {
147b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            return 3+suffix;
1481ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
149b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        if (amt > 9 || (always && zeropad >= 2)) {
150b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            return 2+suffix;
1511ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
152b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        if (always || amt > 0) {
153b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            return 1+suffix;
1541ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
155b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        return 0;
156b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    }
157b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
158b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    static private int printField(char[] formatStr, int amt, char suffix, int pos,
159b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            boolean always, int zeropad) {
160b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        if (always || amt > 0) {
161b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            if ((always && zeropad >= 3) || amt > 99) {
162b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                int dig = amt/100;
163b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                formatStr[pos] = (char)(dig + '0');
164b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                pos++;
165b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                always = true;
166b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                amt -= (dig*100);
167b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            }
168b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            if ((always && zeropad >= 2) || amt > 9) {
169b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                int dig = amt/10;
170b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                formatStr[pos] = (char)(dig + '0');
171b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                pos++;
172b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                always = true;
173b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                amt -= (dig*10);
174b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            }
175b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            formatStr[pos] = (char)(amt + '0');
176b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            pos++;
177b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            formatStr[pos] = suffix;
178b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            pos++;
1791ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
180b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        return pos;
1811ebccf531d1049853b3b0630035434619682c016Dianne Hackborn    }
182b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
183b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    private static int formatDurationLocked(long duration, int fieldLen) {
184b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        if (sFormatStr.length < fieldLen) {
185b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            sFormatStr = new char[fieldLen];
186b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        }
187b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
188b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        char[] formatStr = sFormatStr;
189b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
1901ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        if (duration == 0) {
191b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            int pos = 0;
192b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            fieldLen -= 1;
193b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            while (pos < fieldLen) {
194b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                formatStr[pos] = ' ';
195b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            }
196b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            formatStr[pos] = '0';
197b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            return pos+1;
1981ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
199b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
200b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        char prefix;
2011ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        if (duration > 0) {
202b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            prefix = '+';
2031ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        } else {
204b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            prefix = '-';
2051ebccf531d1049853b3b0630035434619682c016Dianne Hackborn            duration = -duration;
2061ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
2071ebccf531d1049853b3b0630035434619682c016Dianne Hackborn
2081ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        int millis = (int)(duration%1000);
2091ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        int seconds = (int) Math.floor(duration / 1000);
2101ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        int days = 0, hours = 0, minutes = 0;
2111ebccf531d1049853b3b0630035434619682c016Dianne Hackborn
2121ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        if (seconds > SECONDS_PER_DAY) {
2131ebccf531d1049853b3b0630035434619682c016Dianne Hackborn            days = seconds / SECONDS_PER_DAY;
2141ebccf531d1049853b3b0630035434619682c016Dianne Hackborn            seconds -= days * SECONDS_PER_DAY;
2151ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
2161ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        if (seconds > SECONDS_PER_HOUR) {
2171ebccf531d1049853b3b0630035434619682c016Dianne Hackborn            hours = seconds / SECONDS_PER_HOUR;
2181ebccf531d1049853b3b0630035434619682c016Dianne Hackborn            seconds -= hours * SECONDS_PER_HOUR;
2191ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
2201ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        if (seconds > SECONDS_PER_MINUTE) {
2211ebccf531d1049853b3b0630035434619682c016Dianne Hackborn            minutes = seconds / SECONDS_PER_MINUTE;
2221ebccf531d1049853b3b0630035434619682c016Dianne Hackborn            seconds -= minutes * SECONDS_PER_MINUTE;
2231ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
2241ebccf531d1049853b3b0630035434619682c016Dianne Hackborn
225b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        int pos = 0;
226b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
227b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        if (fieldLen != 0) {
228b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            int myLen = accumField(days, 1, false, 0);
229b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            myLen += accumField(hours, 1, myLen > 0, 2);
230b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            myLen += accumField(minutes, 1, myLen > 0, 2);
231b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            myLen += accumField(seconds, 1, myLen > 0, 2);
232b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            myLen += accumField(millis, 2, true, myLen > 0 ? 3 : 0) + 1;
233b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            while (myLen < fieldLen) {
234b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                formatStr[pos] = ' ';
235b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                pos++;
236b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                myLen++;
237b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            }
2381ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
239b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
240b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        formatStr[pos] = prefix;
241b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        pos++;
242b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
243b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        int start = pos;
244b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        boolean zeropad = fieldLen != 0;
245b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        pos = printField(formatStr, days, 'd', pos, false, 0);
246b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        pos = printField(formatStr, hours, 'h', pos, pos != start, zeropad ? 2 : 0);
247b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        pos = printField(formatStr, minutes, 'm', pos, pos != start, zeropad ? 2 : 0);
248b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        pos = printField(formatStr, seconds, 's', pos, pos != start, zeropad ? 2 : 0);
249b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        pos = printField(formatStr, millis, 'm', pos, true, (zeropad && pos != start) ? 3 : 0);
250b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        formatStr[pos] = 's';
251b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        return pos + 1;
252b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    }
253b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
254b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    /** @hide Just for debugging; not internationalized. */
255b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    public static void formatDuration(long duration, StringBuilder builder) {
256b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        synchronized (sFormatSync) {
257b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            int len = formatDurationLocked(duration, 0);
258b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            builder.append(sFormatStr, 0, len);
2591ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
2601ebccf531d1049853b3b0630035434619682c016Dianne Hackborn    }
2611ebccf531d1049853b3b0630035434619682c016Dianne Hackborn
262b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    /** @hide Just for debugging; not internationalized. */
263b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    public static void formatDuration(long duration, PrintWriter pw, int fieldLen) {
264b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        synchronized (sFormatSync) {
265b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            int len = formatDurationLocked(duration, fieldLen);
266b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            pw.print(new String(sFormatStr, 0, len));
267b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        }
268b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    }
2691ebccf531d1049853b3b0630035434619682c016Dianne Hackborn
2701ebccf531d1049853b3b0630035434619682c016Dianne Hackborn    /** @hide Just for debugging; not internationalized. */
271b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    public static void formatDuration(long duration, PrintWriter pw) {
272b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        formatDuration(duration, pw, 0);
273b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    }
274b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn
275b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    /** @hide Just for debugging; not internationalized. */
2761ebccf531d1049853b3b0630035434619682c016Dianne Hackborn    public static void formatDuration(long time, long now, PrintWriter pw) {
2771ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        if (time == 0) {
2781ebccf531d1049853b3b0630035434619682c016Dianne Hackborn            pw.print("--");
2791ebccf531d1049853b3b0630035434619682c016Dianne Hackborn            return;
2801ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
281b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        formatDuration(time-now, pw, 0);
2821ebccf531d1049853b3b0630035434619682c016Dianne Hackborn    }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
284