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; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.SpannableStringBuilder; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Spanned; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.SpannedString; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.R; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Calendar; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Date; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.GregorianCalendar; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Locale; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TimeZone; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.text.SimpleDateFormat; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Utility class for producing strings with formatted date/time. 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project <p> 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This class takes as inputs a format string and a representation of a date/time. 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project The format string controls how the output is generated. 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project </p> 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project <p> 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Formatting characters may be repeated in order to get more detailed representations 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project of that field. For instance, the format character 'M' is used to 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project represent the month. Depending on how many times that character is repeated 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project you get a different representation. 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project </p> 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project <p> 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project For the month of September:<br/> 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project M -> 9<br/> 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MM -> 09<br/> 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MMM -> Sep<br/> 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MMMM -> September 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project </p> 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project <p> 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project The effects of the duplication vary depending on the nature of the field. 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project See the notes on the individual field formatters for details. For purely numeric 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fields such as <code>HOUR</code> adding more copies of the designator will 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zero-pad the value to that number of characters. 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project </p> 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project <p> 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project For 7 minutes past the hour:<br/> 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m -> 7<br/> 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mm -> 07<br/> 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mmm -> 007<br/> 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mmmm -> 0007 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project </p> 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project <p> 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Examples for April 6, 1970 at 3:23am:<br/> 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "MM/dd/yy h:mmaa" -> "04/06/70 3:23am"<br/> 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "MMM dd, yyyy h:mmaa" -> "Apr 6, 1970 3:23am"<br/> 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "MMMM dd, yyyy h:mmaa" -> "April 6, 1970 3:23am"<br/> 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "E, MMMM dd, yyyy h:mmaa" -> "Mon, April 6, 1970 3:23am&<br/> 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "EEEE, MMMM dd, yyyy h:mmaa" -> "Monday, April 6, 1970 3:23am"<br/> 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "'Noteworthy day: 'M/d/yy" -> "Noteworthy day: 4/6/70" 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DateFormat { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Text in the format string that should be copied verbatim rather that 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interpreted as formatting codes must be surrounded by the <code>QUOTE</code> 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project character. If you need to embed a literal <code>QUOTE</code> character in 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project the output text then use two in a row. 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char QUOTE = '\''; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This designator indicates whether the <code>HOUR</code> field is before 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project or after noon. The output is lower-case. 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Examples: 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a -> a or p 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project aa -> am or pm 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char AM_PM = 'a'; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This designator indicates whether the <code>HOUR</code> field is before 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project or after noon. The output is capitalized. 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Examples: 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A -> A or P 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AA -> AM or PM 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char CAPITAL_AM_PM = 'A'; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This designator indicates the day of the month. 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Examples for the 9th of the month: 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d -> 9 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dd -> 09 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char DATE = 'd'; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This designator indicates the name of the day of the week. 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Examples for Sunday: 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project E -> Sun 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EEEE -> Sunday 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char DAY = 'E'; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This designator indicates the hour of the day in 12 hour format. 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Examples for 3pm: 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h -> 3 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hh -> 03 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char HOUR = 'h'; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This designator indicates the hour of the day in 24 hour format. 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Example for 3pm: 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project k -> 15 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Examples for midnight: 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project k -> 0 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project kk -> 00 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char HOUR_OF_DAY = 'k'; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This designator indicates the minute of the hour. 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Examples for 7 minutes past the hour: 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m -> 7 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mm -> 07 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char MINUTE = 'm'; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This designator indicates the month of the year 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Examples for September: 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project M -> 9 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MM -> 09 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MMM -> Sep 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MMMM -> September 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char MONTH = 'M'; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This designator indicates the seconds of the minute. 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Examples for 7 seconds past the minute: 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s -> 7 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ss -> 07 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char SECONDS = 's'; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This designator indicates the offset of the timezone from GMT. 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Example for US/Pacific timezone: 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z -> -0800 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zz -> PST 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char TIME_ZONE = 'z'; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project This designator indicates the year. 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Examples for 2006 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y -> 06 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project yyyy -> 2006 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char YEAR = 'y'; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final Object sLocaleLock = new Object(); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static Locale sIs24HourLocale; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean sIs24Hour; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if user preference is set to 24-hour format. 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the context to use for the content resolver 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if 24 hour time format is selected, false otherwise. 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean is24HourFormat(Context context) { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String value = Settings.System.getString(context.getContentResolver(), 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.System.TIME_12_24); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Locale locale = context.getResources().getConfiguration().locale; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sLocaleLock) { 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sIs24HourLocale != null && sIs24HourLocale.equals(locale)) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sIs24Hour; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project java.text.DateFormat natural = 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project java.text.DateFormat.getTimeInstance( 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project java.text.DateFormat.LONG, locale); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (natural instanceof SimpleDateFormat) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SimpleDateFormat sdf = (SimpleDateFormat) natural; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String pattern = sdf.toPattern(); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pattern.indexOf('H') >= 0) { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project value = "24"; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project value = "12"; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project value = "12"; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sLocaleLock) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sIs24HourLocale = locale; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sIs24Hour = !value.equals("12"); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean b24 = !(value == null || value.equals("12")); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return b24; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns a {@link java.text.DateFormat} object that can format the time according 245af0e7a7394bf1e2596c46f81c3b0302a56daab96Eric Fischer * to the current locale and the user's 12-/24-hour clock preference. 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the application context 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the {@link java.text.DateFormat} object that properly formats the time. 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final java.text.DateFormat getTimeFormat(Context context) { 250af0e7a7394bf1e2596c46f81c3b0302a56daab96Eric Fischer boolean b24 = is24HourFormat(context); 251af0e7a7394bf1e2596c46f81c3b0302a56daab96Eric Fischer int res; 252af0e7a7394bf1e2596c46f81c3b0302a56daab96Eric Fischer 253af0e7a7394bf1e2596c46f81c3b0302a56daab96Eric Fischer if (b24) { 254af0e7a7394bf1e2596c46f81c3b0302a56daab96Eric Fischer res = R.string.twenty_four_hour_time_format; 255af0e7a7394bf1e2596c46f81c3b0302a56daab96Eric Fischer } else { 256af0e7a7394bf1e2596c46f81c3b0302a56daab96Eric Fischer res = R.string.twelve_hour_time_format; 257af0e7a7394bf1e2596c46f81c3b0302a56daab96Eric Fischer } 258af0e7a7394bf1e2596c46f81c3b0302a56daab96Eric Fischer 259af0e7a7394bf1e2596c46f81c3b0302a56daab96Eric Fischer return new java.text.SimpleDateFormat(context.getString(res)); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2635bd644caf73e76750feef1a82b8817d32f5367fcEric Fischer * Returns a {@link java.text.DateFormat} object that can format the date 2645bd644caf73e76750feef1a82b8817d32f5367fcEric Fischer * in short form (such as 12/31/1999) according 265328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer * to the current locale and the user's date-order preference. 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the application context 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the {@link java.text.DateFormat} object that properly formats the date. 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final java.text.DateFormat getDateFormat(Context context) { 270328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer String value = Settings.System.getString(context.getContentResolver(), 271328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer Settings.System.DATE_FORMAT); 272328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer 273328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer return getDateFormatForSetting(context, value); 274328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } 275328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer 276328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer /** 277328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer * Returns a {@link java.text.DateFormat} object to format the date 278328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer * as if the date format setting were set to <code>value</code>, 279328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer * including null to use the locale's default format. 280328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer * @param context the application context 281328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer * @param value the date format setting string to interpret for 282328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer * the current locale 283328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer * @hide 284328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer */ 285328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer public static java.text.DateFormat getDateFormatForSetting(Context context, 286328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer String value) { 28703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer String format = getDateFormatStringForSetting(context, value); 28803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 28903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer return new java.text.SimpleDateFormat(format); 29003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer } 29103a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 29203a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer private static String getDateFormatStringForSetting(Context context, String value) { 293328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer if (value != null) { 294328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer int month = value.indexOf('M'); 295328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer int day = value.indexOf('d'); 296328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer int year = value.indexOf('y'); 297328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer 298328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer if (month >= 0 && day >= 0 && year >= 0) { 299328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer String template = context.getString(R.string.numeric_date_template); 30003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer if (year < month && year < day) { 301328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer if (month < day) { 302328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer value = String.format(template, "yyyy", "MM", "dd"); 303328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } else { 304328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer value = String.format(template, "yyyy", "dd", "MM"); 305328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } 306328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } else if (month < day) { 307328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer if (day < year) { 308328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer value = String.format(template, "MM", "dd", "yyyy"); 309328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } else { // unlikely 310328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer value = String.format(template, "MM", "yyyy", "dd"); 311328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } 312328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } else { // day < month 313328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer if (month < year) { 314328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer value = String.format(template, "dd", "MM", "yyyy"); 315328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } else { // unlikely 316328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer value = String.format(template, "dd", "yyyy", "MM"); 317328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } 318328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } 319328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer 32003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer return value; 321328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } 322328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer } 323328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer 3245bd644caf73e76750feef1a82b8817d32f5367fcEric Fischer /* 325328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer * The setting is not set; use the default. 3265bd644caf73e76750feef1a82b8817d32f5367fcEric Fischer * We use a resource string here instead of just DateFormat.SHORT 3275bd644caf73e76750feef1a82b8817d32f5367fcEric Fischer * so that we get a four-digit year instead a two-digit year. 3285bd644caf73e76750feef1a82b8817d32f5367fcEric Fischer */ 329328769582328192f8f361dcb56f2ad67ad00ae2cEric Fischer value = context.getString(R.string.numeric_date_format); 33003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer return value; 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns a {@link java.text.DateFormat} object that can format the date 3355bd644caf73e76750feef1a82b8817d32f5367fcEric Fischer * in long form (such as December 31, 1999) for the current locale. 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the application context 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the {@link java.text.DateFormat} object that formats the date in long form. 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final java.text.DateFormat getLongDateFormat(Context context) { 3405bd644caf73e76750feef1a82b8817d32f5367fcEric Fischer return java.text.DateFormat.getDateInstance(java.text.DateFormat.LONG); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns a {@link java.text.DateFormat} object that can format the date 3455bd644caf73e76750feef1a82b8817d32f5367fcEric Fischer * in medium form (such as Dec. 31, 1999) for the current locale. 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the application context 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the {@link java.text.DateFormat} object that formats the date in long form. 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final java.text.DateFormat getMediumDateFormat(Context context) { 3505bd644caf73e76750feef1a82b8817d32f5367fcEric Fischer return java.text.DateFormat.getDateInstance(java.text.DateFormat.MEDIUM); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gets the current date format stored as a char array. The array will contain 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3 elements ({@link #DATE}, {@link #MONTH}, and {@link #YEAR}) in the order 35603a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer * specified by the user's format preference. Note that this order is 35703a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer * only appropriate for all-numeric dates; spelled-out (MEDIUM and LONG) 35803a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer * dates will generally contain other punctuation, spaces, or words, 35903a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer * not just the day, month, and year, and not necessarily in the same 36003a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer * order returned here. 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final char[] getDateFormatOrder(Context context) { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char[] order = new char[] {DATE, MONTH, YEAR}; 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String value = getDateFormatString(context); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = 0; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean foundDate = false; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean foundMonth = false; 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean foundYear = false; 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (char c : value.toCharArray()) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!foundDate && (c == DATE)) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project foundDate = true; 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project order[index] = DATE; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index++; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!foundMonth && (c == MONTH)) { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project foundMonth = true; 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project order[index] = MONTH; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index++; 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!foundYear && (c == YEAR)) { 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project foundYear = true; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project order[index] = YEAR; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index++; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return order; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String getDateFormatString(Context context) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String value = Settings.System.getString(context.getContentResolver(), 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.System.DATE_FORMAT); 39503a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer 39603a8017d0fe3b55b69c4328aa0d27bd96a2f1360Eric Fischer return getDateFormatStringForSetting(context, value); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Given a format string and a time in milliseconds since Jan 1, 1970 GMT, returns a 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * CharSequence containing the requested date. 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inFormat the format string, as described in {@link android.text.format.DateFormat} 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inTimeInMillis in milliseconds since Jan 1, 1970 GMT 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a {@link CharSequence} containing the requested text 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final CharSequence format(CharSequence inFormat, long inTimeInMillis) { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return format(inFormat, new Date(inTimeInMillis)); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Given a format string and a {@link java.util.Date} object, returns a CharSequence containing 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the requested date. 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inFormat the format string, as described in {@link android.text.format.DateFormat} 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inDate the date to format 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a {@link CharSequence} containing the requested text 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final CharSequence format(CharSequence inFormat, Date inDate) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Calendar c = new GregorianCalendar(); 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project c.setTime(inDate); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return format(inFormat, c); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Given a format string and a {@link java.util.Calendar} object, returns a CharSequence 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing the requested date. 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inFormat the format string, as described in {@link android.text.format.DateFormat} 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inDate the date to format 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a {@link CharSequence} containing the requested text 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final CharSequence format(CharSequence inFormat, Calendar inDate) { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SpannableStringBuilder s = new SpannableStringBuilder(inFormat); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int c; 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = inFormat.length(); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < len; i += count) { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int temp; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count = 1; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project c = s.charAt(i); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == QUOTE) { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count = appendQuotedText(s, i, len); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = s.length(); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((i + count < len) && (s.charAt(i + count) == c)) { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count++; 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String replacement; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (c) { 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AM_PM: 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = DateUtils.getAMPMString(inDate.get(Calendar.AM_PM)); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case CAPITAL_AM_PM: 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //FIXME: this is the same as AM_PM? no capital? 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = DateUtils.getAMPMString(inDate.get(Calendar.AM_PM)); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case DATE: 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = zeroPad(inDate.get(Calendar.DATE), count); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case DAY: 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project temp = inDate.get(Calendar.DAY_OF_WEEK); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = DateUtils.getDayOfWeekString(temp, 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count < 4 ? 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DateUtils.LENGTH_MEDIUM : 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DateUtils.LENGTH_LONG); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case HOUR: 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project temp = inDate.get(Calendar.HOUR); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 == temp) 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project temp = 12; 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = zeroPad(temp, count); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case HOUR_OF_DAY: 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = zeroPad(inDate.get(Calendar.HOUR_OF_DAY), count); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MINUTE: 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = zeroPad(inDate.get(Calendar.MINUTE), count); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MONTH: 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = getMonthString(inDate, count); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SECONDS: 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = zeroPad(inDate.get(Calendar.SECOND), count); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case TIME_ZONE: 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = getTimeZoneString(inDate, count); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case YEAR: 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = getYearString(inDate, count); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = null; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (replacement != null) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s.replace(i, i + count, replacement); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count = replacement.length(); // CARE: count is used in the for loop above 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = s.length(); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inFormat instanceof Spanned) 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new SpannedString(s); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return s.toString(); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String getMonthString(Calendar inDate, int count) { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int month = inDate.get(Calendar.MONTH); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count >= 4) 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return DateUtils.getMonthString(month, DateUtils.LENGTH_LONG); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (count == 3) 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return DateUtils.getMonthString(month, DateUtils.LENGTH_MEDIUM); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Calendar.JANUARY == 0, so add 1 to month. 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return zeroPad(month+1, count); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String getTimeZoneString(Calendar inDate, int count) { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimeZone tz = inDate.getTimeZone(); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count < 2) { // FIXME: shouldn't this be <= 2 ? 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return formatZoneOffset(inDate.get(Calendar.DST_OFFSET) + 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inDate.get(Calendar.ZONE_OFFSET), 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean dst = inDate.get(Calendar.DST_OFFSET) != 0; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return tz.getDisplayName(dst, TimeZone.SHORT); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String formatZoneOffset(int offset, int count) { 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset /= 1000; // milliseconds to seconds 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder tb = new StringBuilder(); 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset < 0) { 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tb.insert(0, "-"); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset = -offset; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tb.insert(0, "+"); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int hours = offset / 3600; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int minutes = (offset % 3600) / 60; 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tb.append(zeroPad(hours, 2)); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tb.append(zeroPad(minutes, 2)); 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return tb.toString(); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String getYearString(Calendar inDate, int count) { 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int year = inDate.get(Calendar.YEAR); 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (count <= 2) ? zeroPad(year % 100, 2) : String.valueOf(year); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int appendQuotedText(SpannableStringBuilder s, int i, int len) { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i + 1 < len && s.charAt(i + 1) == QUOTE) { 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s.delete(i, i + 1); 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = 0; 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // delete leading quote 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s.delete(i, i + 1); 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i < len) { 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char c = s.charAt(i); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == QUOTE) { 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // QUOTEQUOTE -> QUOTE 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i + 1 < len && s.charAt(i + 1) == QUOTE) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s.delete(i, i + 1); 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len--; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count++; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Closing QUOTE ends quoted text copying 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s.delete(i, i + 1); 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i++; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count++; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return count; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String zeroPad(int inValue, int inMinDigits) { 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String val = String.valueOf(inValue); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (val.length() < inMinDigits) { 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char[] buf = new char[inMinDigits]; 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < inMinDigits; i++) 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[i] = '0'; 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project val.getChars(0, val.length(), buf, inMinDigits - val.length()); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project val = new String(buf); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return val; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 632