FileDocCategorySizeDatePackage
DateFormat.javaAPI DocAndroid 5.1 API25219Thu Mar 12 22:22:10 GMT 2015android.text.format

DateFormat

public class DateFormat extends Object
Utility class for producing strings with formatted date/time.

Most callers should avoid supplying their own format strings to this class' {@code format} methods and rely on the correctly localized ones supplied by the system. This class' factory methods return appropriately-localized {@link java.text.DateFormat} instances, suitable for both formatting and parsing dates. For the canonical documentation of format strings, see {@link java.text.SimpleDateFormat}.

In cases where the system does not provide a suitable pattern, this class offers the {@link #getBestDateTimePattern} method.

The {@code format} methods in this class implement a subset of Unicode UTS #35 patterns. The subset currently supported by this class includes the following format characters: {@code acdEHhLKkLMmsyz}. Up to API level 17, only {@code adEhkMmszy} were supported. Note that this class incorrectly implements {@code k} as if it were {@code H} for backwards compatibility.

See {@link java.text.SimpleDateFormat} for more documentation about patterns, or if you need a more complete or correct implementation. Note that the non-{@code format} methods in this class are implemented by {@code SimpleDateFormat}.

Fields Summary
public static final char
QUOTE
public static final char
AM_PM
public static final char
CAPITAL_AM_PM
public static final char
DATE
public static final char
DAY
public static final char
HOUR
public static final char
HOUR_OF_DAY
public static final char
MINUTE
public static final char
MONTH
public static final char
STANDALONE_MONTH
public static final char
SECONDS
public static final char
TIME_ZONE
public static final char
YEAR
private static final Object
sLocaleLock
private static Locale
sIs24HourLocale
private static boolean
sIs24Hour
Constructors Summary
Methods Summary
private static intappendQuotedText(android.text.SpannableStringBuilder s, int i, int len)

        if (i + 1 < len && s.charAt(i + 1) == QUOTE) {
            s.delete(i, i + 1);
            return 1;
        }

        int count = 0;

        // delete leading quote
        s.delete(i, i + 1);
        len--;

        while (i < len) {
            char c = s.charAt(i);

            if (c == QUOTE) {
                //  QUOTEQUOTE -> QUOTE
                if (i + 1 < len && s.charAt(i + 1) == QUOTE) {

                    s.delete(i, i + 1);
                    len--;
                    count++;
                    i++;
                } else {
                    //  Closing QUOTE ends quoted text copying
                    s.delete(i, i + 1);
                    break;
                }
            } else {
                i++;
                count++;
            }
        }

        return count;
    
public static java.lang.CharSequenceformat(java.lang.CharSequence inFormat, long inTimeInMillis)
Given a format string and a time in milliseconds since Jan 1, 1970 GMT, returns a CharSequence containing the requested date.

param
inFormat the format string, as described in {@link android.text.format.DateFormat}
param
inTimeInMillis in milliseconds since Jan 1, 1970 GMT
return
a {@link CharSequence} containing the requested text

        return format(inFormat, new Date(inTimeInMillis));
    
public static java.lang.CharSequenceformat(java.lang.CharSequence inFormat, java.util.Date inDate)
Given a format string and a {@link java.util.Date} object, returns a CharSequence containing the requested date.

param
inFormat the format string, as described in {@link android.text.format.DateFormat}
param
inDate the date to format
return
a {@link CharSequence} containing the requested text

        Calendar c = new GregorianCalendar();
        c.setTime(inDate);
        return format(inFormat, c);
    
public static java.lang.CharSequenceformat(java.lang.CharSequence inFormat, java.util.Calendar inDate)
Given a format string and a {@link java.util.Calendar} object, returns a CharSequence containing the requested date.

param
inFormat the format string, as described in {@link android.text.format.DateFormat}
param
inDate the date to format
return
a {@link CharSequence} containing the requested text

        SpannableStringBuilder s = new SpannableStringBuilder(inFormat);
        int count;

        LocaleData localeData = LocaleData.get(Locale.getDefault());

        int len = inFormat.length();

        for (int i = 0; i < len; i += count) {
            count = 1;
            int c = s.charAt(i);

            if (c == QUOTE) {
                count = appendQuotedText(s, i, len);
                len = s.length();
                continue;
            }

            while ((i + count < len) && (s.charAt(i + count) == c)) {
                count++;
            }

            String replacement;
            switch (c) {
                case 'A":
                case 'a":
                    replacement = localeData.amPm[inDate.get(Calendar.AM_PM) - Calendar.AM];
                    break;
                case 'd":
                    replacement = zeroPad(inDate.get(Calendar.DATE), count);
                    break;
                case 'c":
                case 'E":
                    replacement = getDayOfWeekString(localeData,
                                                     inDate.get(Calendar.DAY_OF_WEEK), count, c);
                    break;
                case 'K": // hour in am/pm (0-11)
                case 'h": // hour in am/pm (1-12)
                    {
                        int hour = inDate.get(Calendar.HOUR);
                        if (c == 'h" && hour == 0) {
                            hour = 12;
                        }
                        replacement = zeroPad(hour, count);
                    }
                    break;
                case 'H": // hour in day (0-23)
                case 'k": // hour in day (1-24) [but see note below]
                    {
                        int hour = inDate.get(Calendar.HOUR_OF_DAY);
                        // Historically on Android 'k' was interpreted as 'H', which wasn't
                        // implemented, so pretty much all callers that want to format 24-hour
                        // times are abusing 'k'. http://b/8359981.
                        if (false && c == 'k" && hour == 0) {
                            hour = 24;
                        }
                        replacement = zeroPad(hour, count);
                    }
                    break;
                case 'L":
                case 'M":
                    replacement = getMonthString(localeData,
                                                 inDate.get(Calendar.MONTH), count, c);
                    break;
                case 'm":
                    replacement = zeroPad(inDate.get(Calendar.MINUTE), count);
                    break;
                case 's":
                    replacement = zeroPad(inDate.get(Calendar.SECOND), count);
                    break;
                case 'y":
                    replacement = getYearString(inDate.get(Calendar.YEAR), count);
                    break;
                case 'z":
                    replacement = getTimeZoneString(inDate, count);
                    break;
                default:
                    replacement = null;
                    break;
            }

            if (replacement != null) {
                s.replace(i, i + count, replacement);
                count = replacement.length(); // CARE: count is used in the for loop above
                len = s.length();
            }
        }

        if (inFormat instanceof Spanned) {
            return new SpannedString(s);
        } else {
            return s.toString();
        }
    
private static java.lang.StringformatZoneOffset(int offset, int count)

        offset /= 1000; // milliseconds to seconds
        StringBuilder tb = new StringBuilder();

        if (offset < 0) {
            tb.insert(0, "-");
            offset = -offset;
        } else {
            tb.insert(0, "+");
        }

        int hours = offset / 3600;
        int minutes = (offset % 3600) / 60;

        tb.append(zeroPad(hours, 2));
        tb.append(zeroPad(minutes, 2));
        return tb.toString();
    
public static java.lang.StringgetBestDateTimePattern(java.util.Locale locale, java.lang.String skeleton)
Returns the best possible localized form of the given skeleton for the given locale. A skeleton is similar to, and uses the same format characters as, a Unicode UTS #35 pattern.

One difference is that order is irrelevant. For example, "MMMMd" will return "MMMM d" in the {@code en_US} locale, but "d. MMMM" in the {@code de_CH} locale.

Note also in that second example that the necessary punctuation for German was added. For the same input in {@code es_ES}, we'd have even more extra text: "d 'de' MMMM".

This method will automatically correct for grammatical necessity. Given the same "MMMMd" input, this method will return "d LLLL" in the {@code fa_IR} locale, where stand-alone months are necessary. Lengths are preserved where meaningful, so "Md" would give a different result to "MMMd", say, except in a locale such as {@code ja_JP} where there is only one length of month.

This method will only return patterns that are in CLDR, and is useful whenever you know what elements you want in your format string but don't want to make your code specific to any one locale.

param
locale the locale into which the skeleton should be localized
param
skeleton a skeleton as described above
return
a string pattern suitable for use with {@link java.text.SimpleDateFormat}.

        return ICU.getBestDateTimePattern(skeleton, locale);
    
public static java.text.DateFormatgetDateFormat(android.content.Context context)
Returns a {@link java.text.DateFormat} object that can format the date in short form (such as 12/31/1999) according to the current locale and the user's date-order preference.

param
context the application context
return
the {@link java.text.DateFormat} object that properly formats the date.

        String value = Settings.System.getString(context.getContentResolver(),
                Settings.System.DATE_FORMAT);

        return getDateFormatForSetting(context, value);
    
public static java.text.DateFormatgetDateFormatForSetting(android.content.Context context, java.lang.String value)
Returns a {@link java.text.DateFormat} object to format the date as if the date format setting were set to value, including null to use the locale's default format.

param
context the application context
param
value the date format setting string to interpret for the current locale
hide

        String format = getDateFormatStringForSetting(context, value);
        return new java.text.SimpleDateFormat(format);
    
public static char[]getDateFormatOrder(android.content.Context context)
Gets the current date format stored as a char array. Returns a 3 element array containing the day ({@code 'd'}), month ({@code 'M'}), and year ({@code 'y'})) in the order specified by the user's format preference. Note that this order is only appropriate for all-numeric dates; spelled-out (MEDIUM and LONG) dates will generally contain other punctuation, spaces, or words, not just the day, month, and year, and not necessarily in the same order returned here.

        return ICU.getDateFormatOrder(getDateFormatString(context));
    
private static java.lang.StringgetDateFormatString(android.content.Context context)

        String value = Settings.System.getString(context.getContentResolver(),
                Settings.System.DATE_FORMAT);

        return getDateFormatStringForSetting(context, value);
    
private static java.lang.StringgetDateFormatStringForSetting(android.content.Context context, java.lang.String value)

        if (value != null) {
            int month = value.indexOf('M");
            int day = value.indexOf('d");
            int year = value.indexOf('y");

            if (month >= 0 && day >= 0 && year >= 0) {
                String template = context.getString(R.string.numeric_date_template);
                if (year < month && year < day) {
                    if (month < day) {
                        value = String.format(template, "yyyy", "MM", "dd");
                    } else {
                        value = String.format(template, "yyyy", "dd", "MM");
                    }
                } else if (month < day) {
                    if (day < year) {
                        value = String.format(template, "MM", "dd", "yyyy");
                    } else { // unlikely
                        value = String.format(template, "MM", "yyyy", "dd");
                    }
                } else { // day < month
                    if (month < year) {
                        value = String.format(template, "dd", "MM", "yyyy");
                    } else { // unlikely
                        value = String.format(template, "dd", "yyyy", "MM");
                    }
                }

                return value;
            }
        }

        // The setting is not set; use the locale's default.
        LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale);
        return d.shortDateFormat4;
    
private static java.lang.StringgetDayOfWeekString(libcore.icu.LocaleData ld, int day, int count, int kind)

        boolean standalone = (kind == 'c");
        if (count == 5) {
            return standalone ? ld.tinyStandAloneWeekdayNames[day] : ld.tinyWeekdayNames[day];
        } else if (count == 4) {
            return standalone ? ld.longStandAloneWeekdayNames[day] : ld.longWeekdayNames[day];
        } else {
            return standalone ? ld.shortStandAloneWeekdayNames[day] : ld.shortWeekdayNames[day];
        }
    
public static java.text.DateFormatgetLongDateFormat(android.content.Context context)
Returns a {@link java.text.DateFormat} object that can format the date in long form (such as {@code Monday, January 3, 2000}) for the current locale.

param
context the application context
return
the {@link java.text.DateFormat} object that formats the date in long form.

        return java.text.DateFormat.getDateInstance(java.text.DateFormat.LONG);
    
public static java.text.DateFormatgetMediumDateFormat(android.content.Context context)
Returns a {@link java.text.DateFormat} object that can format the date in medium form (such as {@code Jan 3, 2000}) for the current locale.

param
context the application context
return
the {@link java.text.DateFormat} object that formats the date in long form.

        return java.text.DateFormat.getDateInstance(java.text.DateFormat.MEDIUM);
    
private static java.lang.StringgetMonthString(libcore.icu.LocaleData ld, int month, int count, int kind)

        boolean standalone = (kind == 'L");
        if (count == 5) {
            return standalone ? ld.tinyStandAloneMonthNames[month] : ld.tinyMonthNames[month];
        } else if (count == 4) {
            return standalone ? ld.longStandAloneMonthNames[month] : ld.longMonthNames[month];
        } else if (count == 3) {
            return standalone ? ld.shortStandAloneMonthNames[month] : ld.shortMonthNames[month];
        } else {
            // Calendar.JANUARY == 0, so add 1 to month.
            return zeroPad(month+1, count);
        }
    
public static java.text.DateFormatgetTimeFormat(android.content.Context context)
Returns a {@link java.text.DateFormat} object that can format the time according to the current locale and the user's 12-/24-hour clock preference.

param
context the application context
return
the {@link java.text.DateFormat} object that properly formats the time.

        return new java.text.SimpleDateFormat(getTimeFormatString(context));
    
public static java.lang.StringgetTimeFormatString(android.content.Context context)
Returns a String pattern that can be used to format the time according to the current locale and the user's 12-/24-hour clock preference.

param
context the application context
hide

        return getTimeFormatString(context, UserHandle.myUserId());
    
public static java.lang.StringgetTimeFormatString(android.content.Context context, int userHandle)
Returns a String pattern that can be used to format the time according to the current locale and the user's 12-/24-hour clock preference.

param
context the application context
param
userHandle the user handle of the user to query the format for
hide

        LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale);
        return is24HourFormat(context, userHandle) ? d.timeFormat24 : d.timeFormat12;
    
private static java.lang.StringgetTimeZoneString(java.util.Calendar inDate, int count)

        TimeZone tz = inDate.getTimeZone();
        if (count < 2) { // FIXME: shouldn't this be <= 2 ?
            return formatZoneOffset(inDate.get(Calendar.DST_OFFSET) +
                                    inDate.get(Calendar.ZONE_OFFSET),
                                    count);
        } else {
            boolean dst = inDate.get(Calendar.DST_OFFSET) != 0;
            return tz.getDisplayName(dst, TimeZone.SHORT);
        }
    
private static java.lang.StringgetYearString(int year, int count)

        return (count <= 2) ? zeroPad(year % 100, 2)
                            : String.format(Locale.getDefault(), "%d", year);
    
public static booleanhasDesignator(java.lang.CharSequence inFormat, char designator)
Test if a format string contains the given designator. Always returns {@code false} if the input format is {@code null}.

hide

        if (inFormat == null) return false;

        final int length = inFormat.length();

        int c;
        int count;

        for (int i = 0; i < length; i += count) {
            count = 1;
            c = inFormat.charAt(i);

            if (c == QUOTE) {
                count = skipQuotedText(inFormat, i, length);
            } else if (c == designator) {
                return true;
            }
        }

        return false;
    
public static booleanhasSeconds(java.lang.CharSequence inFormat)
Indicates whether the specified format string contains seconds. Always returns false if the input format is null.

param
inFormat the format string, as described in {@link android.text.format.DateFormat}
return
true if the format string contains {@link #SECONDS}, false otherwise
hide

        return hasDesignator(inFormat, SECONDS);
    
public static booleanis24HourFormat(android.content.Context context)
Returns true if user preference is set to 24-hour format.

param
context the context to use for the content resolver
return
true if 24 hour time format is selected, false otherwise.



                                        
         
        return is24HourFormat(context, UserHandle.myUserId());
    
public static booleanis24HourFormat(android.content.Context context, int userHandle)
Returns true if user preference with the given user handle is set to 24-hour format.

param
context the context to use for the content resolver
param
userHandle the user handle of the user to query.
return
true if 24 hour time format is selected, false otherwise.
hide

        String value = Settings.System.getStringForUser(context.getContentResolver(),
                Settings.System.TIME_12_24, userHandle);

        if (value == null) {
            Locale locale = context.getResources().getConfiguration().locale;

            synchronized (sLocaleLock) {
                if (sIs24HourLocale != null && sIs24HourLocale.equals(locale)) {
                    return sIs24Hour;
                }
            }

            java.text.DateFormat natural =
                    java.text.DateFormat.getTimeInstance(java.text.DateFormat.LONG, locale);

            if (natural instanceof SimpleDateFormat) {
                SimpleDateFormat sdf = (SimpleDateFormat) natural;
                String pattern = sdf.toPattern();

                if (pattern.indexOf('H") >= 0) {
                    value = "24";
                } else {
                    value = "12";
                }
            } else {
                value = "12";
            }

            synchronized (sLocaleLock) {
                sIs24HourLocale = locale;
                sIs24Hour = value.equals("24");
            }

            return sIs24Hour;
        }

        return value.equals("24");
    
private static intskipQuotedText(java.lang.CharSequence s, int i, int len)

        if (i + 1 < len && s.charAt(i + 1) == QUOTE) {
            return 2;
        }

        int count = 1;
        // skip leading quote
        i++;

        while (i < len) {
            char c = s.charAt(i);

            if (c == QUOTE) {
                count++;
                //  QUOTEQUOTE -> QUOTE
                if (i + 1 < len && s.charAt(i + 1) == QUOTE) {
                    i++;
                } else {
                    break;
                }
            } else {
                i++;
                count++;
            }
        }

        return count;
    
private static java.lang.StringzeroPad(int inValue, int inMinDigits)

        return String.format(Locale.getDefault(), "%0" + inMinDigits + "d", inValue);