TimeUtils.java revision a0f8bc51aff98c2e23e73069e447f63397471a0a
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 {
37a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson    /** @hide */ public TimeUtils() {}
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "TimeUtils";
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Tries to return a time zone that would have had the specified offset
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and DST value at the specified moment in the specified country.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns null if no suitable zone could be found.
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static TimeZone getTimeZone(int offset, boolean dst, long when, String country) {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (country == null) {
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TimeZone best = null;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Resources r = Resources.getSystem();
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        XmlResourceParser parser = r.getXml(com.android.internal.R.xml.time_zones_by_country);
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Date d = new Date(when);
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TimeZone current = TimeZone.getDefault();
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String currentName = current.getID();
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int currentOffset = current.getOffset(when);
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean currentDst = current.inDaylightTime(d);
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            XmlUtils.beginDocument(parser, "timezones");
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (true) {
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                XmlUtils.nextElement(parser);
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String element = parser.getName();
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (element == null || !(element.equals("timezone"))) {
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String code = parser.getAttributeValue(null, "code");
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (country.equals(code)) {
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (parser.next() == XmlPullParser.TEXT) {
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        String maybe = parser.getText();
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // If the current time zone is from the right country
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // and meets the other known properties, keep it
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // instead of changing to another one.
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (maybe.equals(currentName)) {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (currentOffset == offset && currentDst == dst) {
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                return current;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Otherwise, take the first zone from the right
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // country that has the correct current offset and DST.
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // (Keep iterating instead of returning in case we
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // haven't encountered the current time zone yet.)
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (best == null) {
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            TimeZone tz = TimeZone.getTimeZone(maybe);
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (tz.getOffset(when) == offset &&
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                tz.inDaylightTime(d) == dst) {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                best = tz;
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            }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (XmlPullParserException e) {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Got exception while getting preferred time zone.", e);
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (IOException e) {
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Got exception while getting preferred time zone.", e);
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parser.close();
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return best;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a String indicating the version of the time zone database currently
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in use.  The format of the string is dependent on the underlying time zone
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * database implementation, but will typically contain the year in which the database
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was updated plus a letter from a to z indicating changes made within that year.
120a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson     *
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Time zone database updates should be expected to occur periodically due to
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * political and legal changes that cannot be anticipated in advance.  Therefore,
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when computing the UTC time for a future event, applications should be aware that
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the results may differ following a time zone database update.  This method allows
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * applications to detect that a database change has occurred, and to recalculate any
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cached times accordingly.
127a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson     *
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The time zone database may be assumed to change only when the device runtime
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is restarted.  Therefore, it is not necessary to re-query the database version
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * during the lifetime of an activity.
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static String getTimeZoneDatabaseVersion() {
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return ZoneInfoDB.getVersion();
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1351ebccf531d1049853b3b0630035434619682c016Dianne Hackborn
136b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    /** @hide Field length that can hold 999 days of time */
137b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    public static final int HUNDRED_DAY_FIELD_LEN = 19;
138a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
1391ebccf531d1049853b3b0630035434619682c016Dianne Hackborn    private static final int SECONDS_PER_MINUTE = 60;
1401ebccf531d1049853b3b0630035434619682c016Dianne Hackborn    private static final int SECONDS_PER_HOUR = 60 * 60;
1411ebccf531d1049853b3b0630035434619682c016Dianne Hackborn    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
1421ebccf531d1049853b3b0630035434619682c016Dianne Hackborn
143b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    private static final Object sFormatSync = new Object();
144b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    private static char[] sFormatStr = new char[HUNDRED_DAY_FIELD_LEN+5];
145a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
146b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    static private int accumField(int amt, int suffix, boolean always, int zeropad) {
147b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        if (amt > 99 || (always && zeropad >= 3)) {
148b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            return 3+suffix;
1491ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
150b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        if (amt > 9 || (always && zeropad >= 2)) {
151b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            return 2+suffix;
1521ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
153b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        if (always || amt > 0) {
154b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            return 1+suffix;
1551ebccf531d1049853b3b0630035434619682c016Dianne Hackborn        }
156b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        return 0;
157b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    }
158a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
159b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    static private int printField(char[] formatStr, int amt, char suffix, int pos,
160b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            boolean always, int zeropad) {
161b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        if (always || amt > 0) {
162901b3796fd0954cc4b01bf95dbcbd88d87414e84Bjorn Bringert            final int startPos = pos;
163b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            if ((always && zeropad >= 3) || amt > 99) {
164b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                int dig = amt/100;
165b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                formatStr[pos] = (char)(dig + '0');
166b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                pos++;
167b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                amt -= (dig*100);
168b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            }
169901b3796fd0954cc4b01bf95dbcbd88d87414e84Bjorn Bringert            if ((always && zeropad >= 2) || amt > 9 || startPos != pos) {
170b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                int dig = amt/10;
171b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                formatStr[pos] = (char)(dig + '0');
172b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn                pos++;
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    }
182a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
183b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn    private static int formatDurationLocked(long duration, int fieldLen) {
184b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        if (sFormatStr.length < fieldLen) {
185b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn            sFormatStr = new char[fieldLen];
186b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        }
187a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
188b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        char[] formatStr = sFormatStr;
189a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
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        }
199a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
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;
226a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
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        }
239a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
240b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        formatStr[pos] = prefix;
241b5e3165129a5871cf679a67d9e9323ffad3d4902Dianne Hackborn        pos++;
242a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
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    }
253a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
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    }
274a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson
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