Formatter.java revision 874b35b83613eac69d5a9a35bc62e4ac5efc385c
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.text.format;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
2007481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilsonimport android.net.NetworkUtils;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Utility class to aid in formatting common values that are not covered
2441e2e1f9919c9ae3593610f7e05f0d9cf69ec9b2Joe Malin * by the {@link java.util.Formatter} class in {@link java.util}
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class Formatter {
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Formats a content size to be in the form of bytes, kilobytes, megabytes, etc
3007481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson     *
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Context to use to load the localized units
3207481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson     * @param number size value to be formatted
3307481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson     * @return formatted string with the number
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static String formatFileSize(Context context, long number) {
36bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn        return formatFileSize(context, number, false);
37bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn    }
3807481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson
39bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn    /**
40bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn     * Like {@link #formatFileSize}, but trying to generate shorter numbers
4107481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson     * (showing fewer digits of precision).
42bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn     */
43bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn    public static String formatShortFileSize(Context context, long number) {
44bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn        return formatFileSize(context, number, true);
45bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn    }
4607481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson
47bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn    private static String formatFileSize(Context context, long number, boolean shorter) {
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (context == null) {
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "";
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float result = number;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int suffix = com.android.internal.R.string.byteShort;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (result > 900) {
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            suffix = com.android.internal.R.string.kilobyteShort;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = result / 1024;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (result > 900) {
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            suffix = com.android.internal.R.string.megabyteShort;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = result / 1024;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (result > 900) {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            suffix = com.android.internal.R.string.gigabyteShort;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = result / 1024;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (result > 900) {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            suffix = com.android.internal.R.string.terabyteShort;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = result / 1024;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (result > 900) {
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            suffix = com.android.internal.R.string.petabyteShort;
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = result / 1024;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
74bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn        String value;
75bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn        if (result < 1) {
76bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn            value = String.format("%.2f", result);
77bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn        } else if (result < 10) {
78bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn            if (shorter) {
79bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn                value = String.format("%.1f", result);
80bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn            } else {
81bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn                value = String.format("%.2f", result);
82bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn            }
83bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn        } else if (result < 100) {
84bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn            if (shorter) {
85bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn                value = String.format("%.0f", result);
86bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn            } else {
87bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn                value = String.format("%.2f", result);
88bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn            }
89bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn        } else {
90bfe319e06aa56c081d0d94d64a8181291d7f7388Dianne Hackborn            value = String.format("%.0f", result);
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
927351dd113f26580f3bcc7500746f3a26aecc4260Eric Fischer        return context.getResources().
937351dd113f26580f3bcc7500746f3a26aecc4260Eric Fischer            getString(com.android.internal.R.string.fileSizeSuffix,
947351dd113f26580f3bcc7500746f3a26aecc4260Eric Fischer                      value, context.getString(suffix));
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9607481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
98fbf37c79bdedbdd7b82ad7d5862dd82e3c068590Elliott Hughes     * Returns a string in the canonical IPv4 format ###.###.###.### from a packed integer
99fbf37c79bdedbdd7b82ad7d5862dd82e3c068590Elliott Hughes     * containing the IP address. The IPv4 address is expected to be in little-endian
100fbf37c79bdedbdd7b82ad7d5862dd82e3c068590Elliott Hughes     * format (LSB first). That is, 0x01020304 will return "4.3.2.1".
10107481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson     *
102fbf37c79bdedbdd7b82ad7d5862dd82e3c068590Elliott Hughes     * @deprecated Use {@link java.net.InetAddress#getHostAddress()}, which supports both IPv4 and
103fbf37c79bdedbdd7b82ad7d5862dd82e3c068590Elliott Hughes     *     IPv6 addresses. This method does not support IPv6 addresses.
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10507481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson    @Deprecated
10607481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson    public static String formatIpAddress(int ipv4Address) {
10707481ccd1dcc2912797ec64f0bfa5641b39adceaJesse Wilson        return NetworkUtils.intToInetAddress(ipv4Address).getHostAddress();
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
109260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn
110260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn    private static final int SECONDS_PER_MINUTE = 60;
111260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn    private static final int SECONDS_PER_HOUR = 60 * 60;
112260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
113874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos    private static final int MILLIS_PER_MINUTE = 1000 * 60;
114260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn
115260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn    /**
116260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn     * Returns elapsed time for the given millis, in the following format:
117260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn     * 1 day 5 hrs; will include at most two units, can go down to seconds precision.
118260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn     * @param context the application context
119260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn     * @param millis the elapsed time in milli seconds
120260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn     * @return the formatted elapsed time
121260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn     * @hide
122260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn     */
123260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn    public static String formatShortElapsedTime(Context context, long millis) {
124260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        long secondsLong = millis / 1000;
125260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn
126260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        int days = 0, hours = 0, minutes = 0;
127260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        if (secondsLong >= SECONDS_PER_DAY) {
128260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            days = (int)(secondsLong / SECONDS_PER_DAY);
129260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            secondsLong -= days * SECONDS_PER_DAY;
130260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        }
131260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        if (secondsLong >= SECONDS_PER_HOUR) {
132260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            hours = (int)(secondsLong / SECONDS_PER_HOUR);
133260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            secondsLong -= hours * SECONDS_PER_HOUR;
134260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        }
135260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        if (secondsLong >= SECONDS_PER_MINUTE) {
136260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            minutes = (int)(secondsLong / SECONDS_PER_MINUTE);
137260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            secondsLong -= minutes * SECONDS_PER_MINUTE;
138260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        }
139260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        int seconds = (int)secondsLong;
140260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn
141260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        if (days >= 2) {
142260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            days += (hours+12)/24;
143260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            return context.getString(com.android.internal.R.string.durationDays, days);
144260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        } else if (days > 0) {
145260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            if (hours == 1) {
146260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn                return context.getString(com.android.internal.R.string.durationDayHour, days, hours);
147260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            }
148260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            return context.getString(com.android.internal.R.string.durationDayHours, days, hours);
149260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        } else if (hours >= 2) {
150260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            hours += (minutes+30)/60;
151260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            return context.getString(com.android.internal.R.string.durationHours, hours);
152260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        } else if (hours > 0) {
153260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            if (minutes == 1) {
154260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn                return context.getString(com.android.internal.R.string.durationHourMinute, hours,
155260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn                        minutes);
156260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            }
157260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            return context.getString(com.android.internal.R.string.durationHourMinutes, hours,
158260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn                    minutes);
159260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        } else if (minutes >= 2) {
160260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            minutes += (seconds+30)/60;
161260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            return context.getString(com.android.internal.R.string.durationMinutes, minutes);
162260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        } else if (minutes > 0) {
163260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            if (seconds == 1) {
164260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn                return context.getString(com.android.internal.R.string.durationMinuteSecond, minutes,
165260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn                        seconds);
166260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            }
167260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            return context.getString(com.android.internal.R.string.durationMinuteSeconds, minutes,
168260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn                    seconds);
169260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        } else if (seconds == 1) {
170260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            return context.getString(com.android.internal.R.string.durationSecond, seconds);
171260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        } else {
172260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn            return context.getString(com.android.internal.R.string.durationSeconds, seconds);
173260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn        }
174260c5020ae65ddd14668b8ae496c169082aa13f6Dianne Hackborn    }
175874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos
176874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos    /**
177874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos     * Returns elapsed time for the given millis, in the following format:
178874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos     * 1 day 5 hrs; will include at most two units, can go down to minutes precision.
179874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos     * @param context the application context
180874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos     * @param millis the elapsed time in milli seconds
181874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos     * @return the formatted elapsed time
182874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos     * @hide
183874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos     */
184874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos    public static String formatShortElapsedTimeRoundingUpToMinutes(Context context, long millis) {
185874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos        long minutesRoundedUp = (millis + MILLIS_PER_MINUTE - 1) / MILLIS_PER_MINUTE;
186874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos
187874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos        if (minutesRoundedUp == 0) {
188874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos            return context.getString(com.android.internal.R.string.durationMinutes, 0);
189874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos        } else if (minutesRoundedUp == 1) {
190874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos            return context.getString(com.android.internal.R.string.durationMinute, 1);
191874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos        }
192874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos
193874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos        return formatShortElapsedTime(context, minutesRoundedUp * MILLIS_PER_MINUTE);
194874b35b83613eac69d5a9a35bc62e4ac5efc385cAdrian Roos    }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
196