1cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/*
2cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Copyright (C) 2011 The Android Open Source Project
3cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
4cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * you may not use this file except in compliance with the License.
6cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * You may obtain a copy of the License at
7cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
8cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
10cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
11cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * See the License for the specific language governing permissions and
14cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * limitations under the License.
15cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */
16cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
17cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornpackage android.support.v4.util;
18cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
19cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.io.PrintWriter;
20cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
21cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/**
220574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * Helper for accessing features in {@link android.util.TimeUtils}
230574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * introduced after API level 4 in a backwards compatible fashion.
240574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov *
250574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * @hide
26cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */
27cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornpublic class TimeUtils {
28cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /** @hide Field length that can hold 999 days of time */
29cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public static final int HUNDRED_DAY_FIELD_LEN = 19;
30cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
31cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    private static final int SECONDS_PER_MINUTE = 60;
32cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    private static final int SECONDS_PER_HOUR = 60 * 60;
33cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
34cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
35cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    private static final Object sFormatSync = new Object();
36cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    private static char[] sFormatStr = new char[HUNDRED_DAY_FIELD_LEN+5];
37cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
38cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    static private int accumField(int amt, int suffix, boolean always, int zeropad) {
39cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (amt > 99 || (always && zeropad >= 3)) {
40cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return 3+suffix;
41cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
42cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (amt > 9 || (always && zeropad >= 2)) {
43cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return 2+suffix;
44cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
45cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (always || amt > 0) {
46cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return 1+suffix;
47cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
48cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return 0;
49cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
50cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
51cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    static private int printField(char[] formatStr, int amt, char suffix, int pos,
52cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            boolean always, int zeropad) {
53cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (always || amt > 0) {
54cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            final int startPos = pos;
55cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if ((always && zeropad >= 3) || amt > 99) {
56cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                int dig = amt/100;
57cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                formatStr[pos] = (char)(dig + '0');
58cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                pos++;
59cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                amt -= (dig*100);
60cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
61cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if ((always && zeropad >= 2) || amt > 9 || startPos != pos) {
62cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                int dig = amt/10;
63cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                formatStr[pos] = (char)(dig + '0');
64cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                pos++;
65cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                amt -= (dig*10);
66cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
67cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            formatStr[pos] = (char)(amt + '0');
68cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            pos++;
69cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            formatStr[pos] = suffix;
70cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            pos++;
71cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
72cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return pos;
73cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
74cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
75cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    private static int formatDurationLocked(long duration, int fieldLen) {
76cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (sFormatStr.length < fieldLen) {
77cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            sFormatStr = new char[fieldLen];
78cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
79cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
80cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        char[] formatStr = sFormatStr;
81cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
82cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (duration == 0) {
83cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            int pos = 0;
84cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            fieldLen -= 1;
85cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            while (pos < fieldLen) {
86cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                formatStr[pos] = ' ';
87cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
88cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            formatStr[pos] = '0';
89cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return pos+1;
90cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
91cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
92cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        char prefix;
93cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (duration > 0) {
94cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            prefix = '+';
95cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
96cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            prefix = '-';
97cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            duration = -duration;
98cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
99cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
100cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        int millis = (int)(duration%1000);
101cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        int seconds = (int) Math.floor(duration / 1000);
102cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        int days = 0, hours = 0, minutes = 0;
103cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
104cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (seconds > SECONDS_PER_DAY) {
105cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            days = seconds / SECONDS_PER_DAY;
106cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            seconds -= days * SECONDS_PER_DAY;
107cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
108cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (seconds > SECONDS_PER_HOUR) {
109cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            hours = seconds / SECONDS_PER_HOUR;
110cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            seconds -= hours * SECONDS_PER_HOUR;
111cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
112cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (seconds > SECONDS_PER_MINUTE) {
113cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            minutes = seconds / SECONDS_PER_MINUTE;
114cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            seconds -= minutes * SECONDS_PER_MINUTE;
115cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
116cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
117cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        int pos = 0;
118cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
119cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (fieldLen != 0) {
120cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            int myLen = accumField(days, 1, false, 0);
121cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            myLen += accumField(hours, 1, myLen > 0, 2);
122cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            myLen += accumField(minutes, 1, myLen > 0, 2);
123cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            myLen += accumField(seconds, 1, myLen > 0, 2);
124cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            myLen += accumField(millis, 2, true, myLen > 0 ? 3 : 0) + 1;
125cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            while (myLen < fieldLen) {
126cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                formatStr[pos] = ' ';
127cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                pos++;
128cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                myLen++;
129cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
130cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
131cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
132cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        formatStr[pos] = prefix;
133cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        pos++;
134cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
135cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        int start = pos;
136cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        boolean zeropad = fieldLen != 0;
137cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        pos = printField(formatStr, days, 'd', pos, false, 0);
138cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        pos = printField(formatStr, hours, 'h', pos, pos != start, zeropad ? 2 : 0);
139cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        pos = printField(formatStr, minutes, 'm', pos, pos != start, zeropad ? 2 : 0);
140cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        pos = printField(formatStr, seconds, 's', pos, pos != start, zeropad ? 2 : 0);
141cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        pos = printField(formatStr, millis, 'm', pos, true, (zeropad && pos != start) ? 3 : 0);
142cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        formatStr[pos] = 's';
143cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return pos + 1;
144cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
145cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
146cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /** @hide Just for debugging; not internationalized. */
147cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public static void formatDuration(long duration, StringBuilder builder) {
148cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        synchronized (sFormatSync) {
149cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            int len = formatDurationLocked(duration, 0);
150cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            builder.append(sFormatStr, 0, len);
151cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
152cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
153cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
154cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /** @hide Just for debugging; not internationalized. */
155cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public static void formatDuration(long duration, PrintWriter pw, int fieldLen) {
156cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        synchronized (sFormatSync) {
157cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            int len = formatDurationLocked(duration, fieldLen);
158cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            pw.print(new String(sFormatStr, 0, len));
159cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
160cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
161cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
162cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /** @hide Just for debugging; not internationalized. */
163cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public static void formatDuration(long duration, PrintWriter pw) {
164cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        formatDuration(duration, pw, 0);
165cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
166cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
167cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /** @hide Just for debugging; not internationalized. */
168cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public static void formatDuration(long time, long now, PrintWriter pw) {
169cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (time == 0) {
170cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            pw.print("--");
171cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return;
172cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
173cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        formatDuration(time-now, pw, 0);
174cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
175cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn}
176