DateUtilspublic class DateUtils extends Object This class contains various date-related utilities for creating text for things like
elapsed time and date ranges, strings for days of the week and months, and AM/PM text etc. |
Fields Summary |
---|
private static final Object | sLock | private static android.content.res.Configuration | sLastConfig | private static String | sElapsedFormatMMSS | private static String | sElapsedFormatHMMSS | public static final long | SECOND_IN_MILLIS | public static final long | MINUTE_IN_MILLIS | public static final long | HOUR_IN_MILLIS | public static final long | DAY_IN_MILLIS | public static final long | WEEK_IN_MILLIS | public static final long | YEAR_IN_MILLISThis constant is actually the length of 364 days, not of a year! | public static final int | FORMAT_SHOW_TIME | public static final int | FORMAT_SHOW_WEEKDAY | public static final int | FORMAT_SHOW_YEAR | public static final int | FORMAT_NO_YEAR | public static final int | FORMAT_SHOW_DATE | public static final int | FORMAT_NO_MONTH_DAY | public static final int | FORMAT_12HOUR | public static final int | FORMAT_24HOUR | public static final int | FORMAT_CAP_AMPM | public static final int | FORMAT_NO_NOON | public static final int | FORMAT_CAP_NOON | public static final int | FORMAT_NO_MIDNIGHT | public static final int | FORMAT_CAP_MIDNIGHT | public static final int | FORMAT_UTC | public static final int | FORMAT_ABBREV_TIME | public static final int | FORMAT_ABBREV_WEEKDAY | public static final int | FORMAT_ABBREV_MONTH | public static final int | FORMAT_NUMERIC_DATE | public static final int | FORMAT_ABBREV_RELATIVE | public static final int | FORMAT_ABBREV_ALL | public static final int | FORMAT_CAP_NOON_MIDNIGHT | public static final int | FORMAT_NO_NOON_MIDNIGHT | public static final String | HOUR_MINUTE_24This is not actually the preferred 24-hour date format in all locales. | public static final String | MONTH_FORMAT | public static final String | ABBREV_MONTH_FORMATThis is not actually a useful month name in all locales. | public static final String | NUMERIC_MONTH_FORMAT | public static final String | MONTH_DAY_FORMAT | public static final String | YEAR_FORMAT | public static final String | YEAR_FORMAT_TWO_DIGITS | public static final String | WEEKDAY_FORMAT | public static final String | ABBREV_WEEKDAY_FORMAT | public static final int[] | sameYearTable | public static final int[] | sameMonthTable | public static final int | LENGTH_LONGRequest the full spelled-out name. For use with the 'abbrev' parameter of
{@link #getDayOfWeekString} and {@link #getMonthString}. | public static final int | LENGTH_MEDIUMRequest an abbreviated version of the name. For use with the 'abbrev'
parameter of {@link #getDayOfWeekString} and {@link #getMonthString}. | public static final int | LENGTH_SHORTRequest a shorter abbreviated version of the name.
For use with the 'abbrev' parameter of {@link #getDayOfWeekString} and {@link #getMonthString}. | public static final int | LENGTH_SHORTERRequest an even shorter abbreviated version of the name.
Do not use this. Currently this will always return the same result
as {@link #LENGTH_SHORT}. | public static final int | LENGTH_SHORTESTRequest an even shorter abbreviated version of the name.
For use with the 'abbrev' parameter of {@link #getDayOfWeekString} and {@link #getMonthString}. | private static Time | sNowTime | private static Time | sThenTime |
Methods Summary |
---|
public static java.lang.String | formatDateRange(android.content.Context context, long startMillis, long endMillis, int flags)Formats a date or a time range according to the local conventions.
Note that this is a convenience method. Using it involves creating an
internal {@link java.util.Formatter} instance on-the-fly, which is
somewhat costly in terms of memory and time. This is probably acceptable
if you use the method only rarely, but if you rely on it for formatting a
large number of dates, consider creating and reusing your own
{@link java.util.Formatter} instance and use the version of
{@link #formatDateRange(Context, long, long, int) formatDateRange}
that takes a {@link java.util.Formatter}.
Formatter f = new Formatter(new StringBuilder(50), Locale.getDefault());
return formatDateRange(context, f, startMillis, endMillis, flags).toString();
| public static java.util.Formatter | formatDateRange(android.content.Context context, java.util.Formatter formatter, long startMillis, long endMillis, int flags)Formats a date or a time range according to the local conventions.
Note that this is a convenience method for formatting the date or
time range in the local time zone. If you want to specify the time
zone please use
{@link #formatDateRange(Context, Formatter, long, long, int, String) formatDateRange}.
return formatDateRange(context, formatter, startMillis, endMillis, flags, null);
| public static java.util.Formatter | formatDateRange(android.content.Context context, java.util.Formatter formatter, long startMillis, long endMillis, int flags, java.lang.String timeZone)Formats a date or a time range according to the local conventions.
Example output strings (date formats in these examples are shown using
the US date format convention but that may change depending on the
local settings):
- 10:15am
- 3:00pm - 4:00pm
- 3pm - 4pm
- 3PM - 4PM
- 08:00 - 17:00
- Oct 9
- Tue, Oct 9
- October 9, 2007
- Oct 9 - 10
- Oct 9 - 10, 2007
- Oct 28 - Nov 3, 2007
- Dec 31, 2007 - Jan 1, 2008
- Oct 9, 8:00am - Oct 10, 5:00pm
- 12/31/2007 - 01/01/2008
The flags argument is a bitmask of options from the following list:
- FORMAT_SHOW_TIME
- FORMAT_SHOW_WEEKDAY
- FORMAT_SHOW_YEAR
- FORMAT_SHOW_DATE
- FORMAT_NO_MONTH_DAY
- FORMAT_12HOUR
- FORMAT_24HOUR
- FORMAT_CAP_AMPM
- FORMAT_NO_NOON
- FORMAT_CAP_NOON
- FORMAT_NO_MIDNIGHT
- FORMAT_CAP_MIDNIGHT
- FORMAT_UTC
- FORMAT_ABBREV_TIME
- FORMAT_ABBREV_WEEKDAY
- FORMAT_ABBREV_MONTH
- FORMAT_ABBREV_ALL
- FORMAT_NUMERIC_DATE
If FORMAT_SHOW_TIME is set, the time is shown as part of the date range.
If the start and end time are the same, then just the start time is
shown.
If FORMAT_SHOW_WEEKDAY is set, then the weekday is shown.
If FORMAT_SHOW_YEAR is set, then the year is always shown.
If FORMAT_SHOW_YEAR is not set, then the year
is shown only if it is different from the current year, or if the start
and end dates fall on different years.
Normally the date is shown unless the start and end day are the same.
If FORMAT_SHOW_DATE is set, then the date is always shown, even for
same day ranges.
If FORMAT_NO_MONTH_DAY is set, then if the date is shown, just the
month name will be shown, not the day of the month. For example,
"January, 2008" instead of "January 6 - 12, 2008".
If FORMAT_CAP_AMPM is set and 12-hour time is used, then the "AM"
and "PM" are capitalized. You should not use this flag
because in some locales these terms cannot be capitalized, and in
many others it doesn't make sense to do so even though it is possible.
If FORMAT_NO_NOON is set and 12-hour time is used, then "12pm" is
shown instead of "noon".
If FORMAT_CAP_NOON is set and 12-hour time is used, then "Noon" is
shown instead of "noon". You should probably not use this flag
because in many locales it will not make sense to capitalize
the term.
If FORMAT_NO_MIDNIGHT is set and 12-hour time is used, then "12am" is
shown instead of "midnight".
If FORMAT_CAP_MIDNIGHT is set and 12-hour time is used, then "Midnight"
is shown instead of "midnight". You should probably not use this
flag because in many locales it will not make sense to capitalize
the term.
If FORMAT_12HOUR is set and the time is shown, then the time is
shown in the 12-hour time format. You should not normally set this.
Instead, let the time format be chosen automatically according to the
system settings. If both FORMAT_12HOUR and FORMAT_24HOUR are set, then
FORMAT_24HOUR takes precedence.
If FORMAT_24HOUR is set and the time is shown, then the time is
shown in the 24-hour time format. You should not normally set this.
Instead, let the time format be chosen automatically according to the
system settings. If both FORMAT_12HOUR and FORMAT_24HOUR are set, then
FORMAT_24HOUR takes precedence.
If FORMAT_UTC is set, then the UTC time zone is used for the start
and end milliseconds unless a time zone is specified. If a time zone
is specified it will be used regardless of the FORMAT_UTC flag.
If FORMAT_ABBREV_TIME is set and 12-hour time format is used, then the
start and end times (if shown) are abbreviated by not showing the minutes
if they are zero. For example, instead of "3:00pm" the time would be
abbreviated to "3pm".
If FORMAT_ABBREV_WEEKDAY is set, then the weekday (if shown) is
abbreviated to a 3-letter string.
If FORMAT_ABBREV_MONTH is set, then the month (if shown) is abbreviated
to a 3-letter string.
If FORMAT_ABBREV_ALL is set, then the weekday and the month (if shown)
are abbreviated to 3-letter strings.
If FORMAT_NUMERIC_DATE is set, then the date is shown in numeric format
instead of using the name of the month. For example, "12/31/2008"
instead of "December 31, 2008".
If the end date ends at 12:00am at the beginning of a day, it is
formatted as the end of the previous day in two scenarios:
- For single day events. This results in "8pm - midnight" instead of
"Nov 10, 8pm - Nov 11, 12am".
- When the time is not displayed. This results in "Nov 10 - 11" for
an event with a start date of Nov 10 and an end date of Nov 12 at
00:00.
// If we're being asked to format a time without being explicitly told whether to use
// the 12- or 24-hour clock, icu4c will fall back to the locale's preferred 12/24 format,
// but we want to fall back to the user's preference.
if ((flags & (FORMAT_SHOW_TIME | FORMAT_12HOUR | FORMAT_24HOUR)) == FORMAT_SHOW_TIME) {
flags |= DateFormat.is24HourFormat(context) ? FORMAT_24HOUR : FORMAT_12HOUR;
}
String range = DateIntervalFormat.formatDateRange(startMillis, endMillis, flags, timeZone);
try {
formatter.out().append(range);
} catch (IOException impossible) {
throw new AssertionError(impossible);
}
return formatter;
| public static java.lang.String | formatDateTime(android.content.Context context, long millis, int flags)Formats a date or a time according to the local conventions. There are
lots of options that allow the caller to control, for example, if the
time is shown, if the day of the week is shown, if the month name is
abbreviated, if noon is shown instead of 12pm, and so on. For the
complete list of options, see the documentation for
{@link #formatDateRange}.
Example output strings (date formats in these examples are shown using
the US date format convention but that may change depending on the
local settings):
- 10:15am
- 3:00pm
- 3pm
- 3PM
- 08:00
- 17:00
- noon
- Noon
- midnight
- Midnight
- Oct 31
- Oct 31, 2007
- October 31, 2007
- 10am, Oct 31
- 17:00, Oct 31
- Wed
- Wednesday
- 10am, Wed, Oct 31
- Wed, Oct 31
- Wednesday, Oct 31
- Wed, Oct 31, 2007
- Wed, October 31
- 10/31/2007
return formatDateRange(context, millis, millis, flags);
| public static java.lang.CharSequence | formatDuration(long millis)Return given duration in a human-friendly format. For example, "4
minutes" or "1 second". Returns only largest meaningful unit of time,
from seconds up to hours.
final Resources res = Resources.getSystem();
if (millis >= HOUR_IN_MILLIS) {
final int hours = (int) ((millis + 1800000) / HOUR_IN_MILLIS);
return res.getQuantityString(
com.android.internal.R.plurals.duration_hours, hours, hours);
} else if (millis >= MINUTE_IN_MILLIS) {
final int minutes = (int) ((millis + 30000) / MINUTE_IN_MILLIS);
return res.getQuantityString(
com.android.internal.R.plurals.duration_minutes, minutes, minutes);
} else {
final int seconds = (int) ((millis + 500) / SECOND_IN_MILLIS);
return res.getQuantityString(
com.android.internal.R.plurals.duration_seconds, seconds, seconds);
}
| public static java.lang.String | formatElapsedTime(long elapsedSeconds)Formats an elapsed time in the form "MM:SS" or "H:MM:SS"
for display on the call-in-progress screen.
return formatElapsedTime(null, elapsedSeconds);
| public static java.lang.String | formatElapsedTime(java.lang.StringBuilder recycle, long elapsedSeconds)Formats an elapsed time in a format like "MM:SS" or "H:MM:SS" (using a form
suited to the current locale), similar to that used on the call-in-progress
screen.
// Break the elapsed seconds into hours, minutes, and seconds.
long hours = 0;
long minutes = 0;
long seconds = 0;
if (elapsedSeconds >= 3600) {
hours = elapsedSeconds / 3600;
elapsedSeconds -= hours * 3600;
}
if (elapsedSeconds >= 60) {
minutes = elapsedSeconds / 60;
elapsedSeconds -= minutes * 60;
}
seconds = elapsedSeconds;
// Create a StringBuilder if we weren't given one to recycle.
// TODO: if we cared, we could have a thread-local temporary StringBuilder.
StringBuilder sb = recycle;
if (sb == null) {
sb = new StringBuilder(8);
} else {
sb.setLength(0);
}
// Format the broken-down time in a locale-appropriate way.
// TODO: use icu4c when http://unicode.org/cldr/trac/ticket/3407 is fixed.
Formatter f = new Formatter(sb, Locale.getDefault());
initFormatStrings();
if (hours > 0) {
return f.format(sElapsedFormatHMMSS, hours, minutes, seconds).toString();
} else {
return f.format(sElapsedFormatMMSS, minutes, seconds).toString();
}
| public static final java.lang.CharSequence | formatSameDayTime(long then, long now, int dateStyle, int timeStyle)Format a date / time such that if the then is on the same day as now, it shows
just the time and if it's a different day, it shows just the date.
The parameters dateFormat and timeFormat should each be one of
{@link java.text.DateFormat#DEFAULT},
{@link java.text.DateFormat#FULL},
{@link java.text.DateFormat#LONG},
{@link java.text.DateFormat#MEDIUM}
or
{@link java.text.DateFormat#SHORT}
Calendar thenCal = new GregorianCalendar();
thenCal.setTimeInMillis(then);
Date thenDate = thenCal.getTime();
Calendar nowCal = new GregorianCalendar();
nowCal.setTimeInMillis(now);
java.text.DateFormat f;
if (thenCal.get(Calendar.YEAR) == nowCal.get(Calendar.YEAR)
&& thenCal.get(Calendar.MONTH) == nowCal.get(Calendar.MONTH)
&& thenCal.get(Calendar.DAY_OF_MONTH) == nowCal.get(Calendar.DAY_OF_MONTH)) {
f = java.text.DateFormat.getTimeInstance(timeStyle);
} else {
f = java.text.DateFormat.getDateInstance(dateStyle);
}
return f.format(thenDate);
| public static java.lang.String | getAMPMString(int ampm)Return a localized string for AM or PM.
return LocaleData.get(Locale.getDefault()).amPm[ampm - Calendar.AM];
| public static java.lang.String | getDayOfWeekString(int dayOfWeek, int abbrev)Return a string for the day of the week.
LocaleData d = LocaleData.get(Locale.getDefault());
String[] names;
switch (abbrev) {
case LENGTH_LONG: names = d.longWeekdayNames; break;
case LENGTH_MEDIUM: names = d.shortWeekdayNames; break;
case LENGTH_SHORT: names = d.shortWeekdayNames; break; // TODO
case LENGTH_SHORTER: names = d.shortWeekdayNames; break; // TODO
case LENGTH_SHORTEST: names = d.tinyWeekdayNames; break;
default: names = d.shortWeekdayNames; break;
}
return names[dayOfWeek];
| public static java.lang.String | getMonthString(int month, int abbrev)Return a localized string for the month of the year.
LocaleData d = LocaleData.get(Locale.getDefault());
String[] names;
switch (abbrev) {
case LENGTH_LONG: names = d.longMonthNames; break;
case LENGTH_MEDIUM: names = d.shortMonthNames; break;
case LENGTH_SHORT: names = d.shortMonthNames; break;
case LENGTH_SHORTER: names = d.shortMonthNames; break;
case LENGTH_SHORTEST: names = d.tinyMonthNames; break;
default: names = d.shortMonthNames; break;
}
return names[month];
| public static java.lang.CharSequence | getRelativeDateTimeString(android.content.Context c, long time, long minResolution, long transitionResolution, int flags)Return string describing the elapsed time since startTime formatted like
"[relative time/date], [time]".
Example output strings for the US date format.
- 3 mins ago, 10:15 AM
- yesterday, 12:20 PM
- Dec 12, 4:12 AM
- 11/14/2007, 8:20 AM
Resources r = Resources.getSystem();
long now = System.currentTimeMillis();
long duration = Math.abs(now - time);
// getRelativeTimeSpanString() doesn't correctly format relative dates
// above a week or exact dates below a day, so clamp
// transitionResolution as needed.
if (transitionResolution > WEEK_IN_MILLIS) {
transitionResolution = WEEK_IN_MILLIS;
} else if (transitionResolution < DAY_IN_MILLIS) {
transitionResolution = DAY_IN_MILLIS;
}
CharSequence timeClause = formatDateRange(c, time, time, FORMAT_SHOW_TIME);
String result;
if (duration < transitionResolution) {
CharSequence relativeClause = getRelativeTimeSpanString(time, now, minResolution, flags);
result = r.getString(com.android.internal.R.string.relative_time, relativeClause, timeClause);
} else {
CharSequence dateClause = getRelativeTimeSpanString(c, time, false);
result = r.getString(com.android.internal.R.string.date_time, dateClause, timeClause);
}
return result;
| private static final java.lang.String | getRelativeDayString(android.content.res.Resources r, long day, long today)Returns a string describing a day relative to the current day. For example if the day is
today this function returns "Today", if the day was a week ago it returns "7 days ago", and
if the day is in 2 weeks it returns "in 14 days".
Locale locale = r.getConfiguration().locale;
if (locale == null) {
locale = Locale.getDefault();
}
// TODO: use TimeZone.getOffset instead.
Time startTime = new Time();
startTime.set(day);
int startDay = Time.getJulianDay(day, startTime.gmtoff);
Time currentTime = new Time();
currentTime.set(today);
int currentDay = Time.getJulianDay(today, currentTime.gmtoff);
int days = Math.abs(currentDay - startDay);
boolean past = (today > day);
// TODO: some locales name other days too, such as de_DE's "Vorgestern" (today - 2).
if (days == 1) {
if (past) {
return LocaleData.get(locale).yesterday;
} else {
return LocaleData.get(locale).tomorrow;
}
} else if (days == 0) {
return LocaleData.get(locale).today;
}
int resId;
if (past) {
resId = com.android.internal.R.plurals.num_days_ago;
} else {
resId = com.android.internal.R.plurals.in_num_days;
}
String format = r.getQuantityString(resId, days);
return String.format(format, days);
| public static java.lang.CharSequence | getRelativeTimeSpanString(android.content.Context c, long millis, boolean withPreposition)
String result;
long now = System.currentTimeMillis();
long span = Math.abs(now - millis);
synchronized (DateUtils.class) {
if (sNowTime == null) {
sNowTime = new Time();
}
if (sThenTime == null) {
sThenTime = new Time();
}
sNowTime.set(now);
sThenTime.set(millis);
int prepositionId;
if (span < DAY_IN_MILLIS && sNowTime.weekDay == sThenTime.weekDay) {
// Same day
int flags = FORMAT_SHOW_TIME;
result = formatDateRange(c, millis, millis, flags);
prepositionId = R.string.preposition_for_time;
} else if (sNowTime.year != sThenTime.year) {
// Different years
int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE;
result = formatDateRange(c, millis, millis, flags);
// This is a date (like "10/31/2008" so use the date preposition)
prepositionId = R.string.preposition_for_date;
} else {
// Default
int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH;
result = formatDateRange(c, millis, millis, flags);
prepositionId = R.string.preposition_for_date;
}
if (withPreposition) {
Resources res = c.getResources();
result = res.getString(prepositionId, result);
}
}
return result;
| public static java.lang.CharSequence | getRelativeTimeSpanString(android.content.Context c, long millis)Convenience function to return relative time string without preposition.
return getRelativeTimeSpanString(c, millis, false /* no preposition */);
| public static java.lang.CharSequence | getRelativeTimeSpanString(long startTime)Returns a string describing the elapsed time since startTime.
return getRelativeTimeSpanString(startTime, System.currentTimeMillis(), MINUTE_IN_MILLIS);
| public static java.lang.CharSequence | getRelativeTimeSpanString(long time, long now, long minResolution)Returns a string describing 'time' as a time relative to 'now'.
Time spans in the past are formatted like "42 minutes ago".
Time spans in the future are formatted like "in 42 minutes".
int flags = FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR | FORMAT_ABBREV_MONTH;
return getRelativeTimeSpanString(time, now, minResolution, flags);
| public static java.lang.CharSequence | getRelativeTimeSpanString(long time, long now, long minResolution, int flags)Returns a string describing 'time' as a time relative to 'now'.
Time spans in the past are formatted like "42 minutes ago". Time spans in
the future are formatted like "in 42 minutes".
Can use {@link #FORMAT_ABBREV_RELATIVE} flag to use abbreviated relative
times, like "42 mins ago".
Resources r = Resources.getSystem();
boolean abbrevRelative = (flags & (FORMAT_ABBREV_RELATIVE | FORMAT_ABBREV_ALL)) != 0;
boolean past = (now >= time);
long duration = Math.abs(now - time);
int resId;
long count;
if (duration < MINUTE_IN_MILLIS && minResolution < MINUTE_IN_MILLIS) {
count = duration / SECOND_IN_MILLIS;
if (past) {
if (abbrevRelative) {
resId = com.android.internal.R.plurals.abbrev_num_seconds_ago;
} else {
resId = com.android.internal.R.plurals.num_seconds_ago;
}
} else {
if (abbrevRelative) {
resId = com.android.internal.R.plurals.abbrev_in_num_seconds;
} else {
resId = com.android.internal.R.plurals.in_num_seconds;
}
}
} else if (duration < HOUR_IN_MILLIS && minResolution < HOUR_IN_MILLIS) {
count = duration / MINUTE_IN_MILLIS;
if (past) {
if (abbrevRelative) {
resId = com.android.internal.R.plurals.abbrev_num_minutes_ago;
} else {
resId = com.android.internal.R.plurals.num_minutes_ago;
}
} else {
if (abbrevRelative) {
resId = com.android.internal.R.plurals.abbrev_in_num_minutes;
} else {
resId = com.android.internal.R.plurals.in_num_minutes;
}
}
} else if (duration < DAY_IN_MILLIS && minResolution < DAY_IN_MILLIS) {
count = duration / HOUR_IN_MILLIS;
if (past) {
if (abbrevRelative) {
resId = com.android.internal.R.plurals.abbrev_num_hours_ago;
} else {
resId = com.android.internal.R.plurals.num_hours_ago;
}
} else {
if (abbrevRelative) {
resId = com.android.internal.R.plurals.abbrev_in_num_hours;
} else {
resId = com.android.internal.R.plurals.in_num_hours;
}
}
} else if (duration < WEEK_IN_MILLIS && minResolution < WEEK_IN_MILLIS) {
return getRelativeDayString(r, time, now);
} else {
// We know that we won't be showing the time, so it is safe to pass
// in a null context.
return formatDateRange(null, time, time, flags);
}
String format = r.getQuantityString(resId, (int) count);
return String.format(format, count);
| private static void | initFormatStrings()
synchronized (sLock) {
initFormatStringsLocked();
}
| private static void | initFormatStringsLocked()
Resources r = Resources.getSystem();
Configuration cfg = r.getConfiguration();
if (sLastConfig == null || !sLastConfig.equals(cfg)) {
sLastConfig = cfg;
sElapsedFormatMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_mm_ss);
sElapsedFormatHMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_h_mm_ss);
}
| public static boolean | isToday(long when)
Time time = new Time();
time.set(when);
int thenYear = time.year;
int thenMonth = time.month;
int thenMonthDay = time.monthDay;
time.set(System.currentTimeMillis());
return (thenYear == time.year)
&& (thenMonth == time.month)
&& (thenMonthDay == time.monthDay);
|
|