summaryrefslogtreecommitdiffstats
path: root/java/com/android/contacts/common/util/DateUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/contacts/common/util/DateUtils.java')
-rw-r--r--java/com/android/contacts/common/util/DateUtils.java241
1 files changed, 0 insertions, 241 deletions
diff --git a/java/com/android/contacts/common/util/DateUtils.java b/java/com/android/contacts/common/util/DateUtils.java
index 1935d727a..09d52bce8 100644
--- a/java/com/android/contacts/common/util/DateUtils.java
+++ b/java/com/android/contacts/common/util/DateUtils.java
@@ -16,252 +16,11 @@
package com.android.contacts.common.util;
-import android.content.Context;
-import android.text.format.DateFormat;
import android.text.format.Time;
-import java.text.ParsePosition;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-import java.util.TimeZone;
/** Utility methods for processing dates. */
public class DateUtils {
- public static final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("UTC");
-
- /**
- * When parsing a date without a year, the system assumes 1970, which wasn't a leap-year. Let's
- * add a one-off hack for that day of the year
- */
- public static final String NO_YEAR_DATE_FEB29TH = "--02-29";
-
- // Variations of ISO 8601 date format. Do not change the order - it does affect the
- // result in ambiguous cases.
- private static final SimpleDateFormat[] DATE_FORMATS = {
- CommonDateUtils.FULL_DATE_FORMAT,
- CommonDateUtils.DATE_AND_TIME_FORMAT,
- new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.US),
- new SimpleDateFormat("yyyyMMdd", Locale.US),
- new SimpleDateFormat("yyyyMMdd'T'HHmmssSSS'Z'", Locale.US),
- new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.US),
- new SimpleDateFormat("yyyyMMdd'T'HHmm'Z'", Locale.US),
- };
-
- static {
- for (SimpleDateFormat format : DATE_FORMATS) {
- format.setLenient(true);
- format.setTimeZone(UTC_TIMEZONE);
- }
- CommonDateUtils.NO_YEAR_DATE_FORMAT.setTimeZone(UTC_TIMEZONE);
- }
-
- /**
- * Parses the supplied string to see if it looks like a date.
- *
- * @param string The string representation of the provided date
- * @param mustContainYear If true, the string is parsed as a date containing a year. If false, the
- * string is parsed into a valid date even if the year field is missing.
- * @return A Calendar object corresponding to the date if the string is successfully parsed. If
- * not, null is returned.
- */
- public static Calendar parseDate(String string, boolean mustContainYear) {
- ParsePosition parsePosition = new ParsePosition(0);
- Date date;
- if (!mustContainYear) {
- final boolean noYearParsed;
- // Unfortunately, we can't parse Feb 29th correctly, so let's handle this day seperately
- if (NO_YEAR_DATE_FEB29TH.equals(string)) {
- return getUtcDate(0, Calendar.FEBRUARY, 29);
- } else {
- synchronized (CommonDateUtils.NO_YEAR_DATE_FORMAT) {
- date = CommonDateUtils.NO_YEAR_DATE_FORMAT.parse(string, parsePosition);
- }
- noYearParsed = parsePosition.getIndex() == string.length();
- }
-
- if (noYearParsed) {
- return getUtcDate(date, true);
- }
- }
- for (int i = 0; i < DATE_FORMATS.length; i++) {
- SimpleDateFormat f = DATE_FORMATS[i];
- synchronized (f) {
- parsePosition.setIndex(0);
- date = f.parse(string, parsePosition);
- if (parsePosition.getIndex() == string.length()) {
- return getUtcDate(date, false);
- }
- }
- }
- return null;
- }
-
- private static final Calendar getUtcDate(Date date, boolean noYear) {
- final Calendar calendar = Calendar.getInstance(UTC_TIMEZONE, Locale.US);
- calendar.setTime(date);
- if (noYear) {
- calendar.set(Calendar.YEAR, 0);
- }
- return calendar;
- }
-
- private static final Calendar getUtcDate(int year, int month, int dayOfMonth) {
- final Calendar calendar = Calendar.getInstance(UTC_TIMEZONE, Locale.US);
- calendar.clear();
- calendar.set(Calendar.YEAR, year);
- calendar.set(Calendar.MONTH, month);
- calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
- return calendar;
- }
-
- public static boolean isYearSet(Calendar cal) {
- // use the Calendar.YEAR field to track whether or not the year is set instead of
- // Calendar.isSet() because doing Calendar.get() causes Calendar.isSet() to become
- // true irregardless of what the previous value was
- return cal.get(Calendar.YEAR) > 1;
- }
-
- /**
- * Same as {@link #formatDate(Context context, String string, boolean longForm)}, with longForm
- * set to {@code true} by default.
- *
- * @param context Valid context
- * @param string String representation of a date to parse
- * @return Returns the same date in a cleaned up format. If the supplied string does not look like
- * a date, return it unchanged.
- */
- public static String formatDate(Context context, String string) {
- return formatDate(context, string, true);
- }
-
- /**
- * Parses the supplied string to see if it looks like a date.
- *
- * @param context Valid context
- * @param string String representation of a date to parse
- * @param longForm If true, return the date formatted into its long string representation. If
- * false, return the date formatted using its short form representation (i.e. 12/11/2012)
- * @return Returns the same date in a cleaned up format. If the supplied string does not look like
- * a date, return it unchanged.
- */
- public static String formatDate(Context context, String string, boolean longForm) {
- if (string == null) {
- return null;
- }
-
- string = string.trim();
- if (string.length() == 0) {
- return string;
- }
- final Calendar cal = parseDate(string, false);
-
- // we weren't able to parse the string successfully so just return it unchanged
- if (cal == null) {
- return string;
- }
-
- final boolean isYearSet = isYearSet(cal);
- final java.text.DateFormat outFormat;
- if (!isYearSet) {
- outFormat = getLocalizedDateFormatWithoutYear(context);
- } else {
- outFormat =
- longForm ? DateFormat.getLongDateFormat(context) : DateFormat.getDateFormat(context);
- }
- synchronized (outFormat) {
- outFormat.setTimeZone(UTC_TIMEZONE);
- return outFormat.format(cal.getTime());
- }
- }
-
- public static boolean isMonthBeforeDay(Context context) {
- char[] dateFormatOrder = DateFormat.getDateFormatOrder(context);
- for (int i = 0; i < dateFormatOrder.length; i++) {
- if (dateFormatOrder[i] == 'd') {
- return false;
- }
- if (dateFormatOrder[i] == 'M') {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns a SimpleDateFormat object without the year fields by using a regular expression to
- * eliminate the year in the string pattern. In the rare occurence that the resulting pattern
- * cannot be reconverted into a SimpleDateFormat, it uses the provided context to determine
- * whether the month field should be displayed before the day field, and returns either "MMMM dd"
- * or "dd MMMM" converted into a SimpleDateFormat.
- */
- public static java.text.DateFormat getLocalizedDateFormatWithoutYear(Context context) {
- final String pattern =
- ((SimpleDateFormat) SimpleDateFormat.getDateInstance(java.text.DateFormat.LONG))
- .toPattern();
- // Determine the correct regex pattern for year.
- // Special case handling for Spanish locale by checking for "de"
- final String yearPattern =
- pattern.contains("de") ? "[^Mm]*[Yy]+[^Mm]*" : "[^DdMm]*[Yy]+[^DdMm]*";
- try {
- // Eliminate the substring in pattern that matches the format for that of year
- return new SimpleDateFormat(pattern.replaceAll(yearPattern, ""));
- } catch (IllegalArgumentException e) {
- return new SimpleDateFormat(DateUtils.isMonthBeforeDay(context) ? "MMMM dd" : "dd MMMM");
- }
- }
-
- /**
- * Given a calendar (possibly containing only a day of the year), returns the earliest possible
- * anniversary of the date that is equal to or after the current point in time if the date does
- * not contain a year, or the date converted to the local time zone (if the date contains a year.
- *
- * @param target The date we wish to convert(in the UTC time zone).
- * @return If date does not contain a year (year < 1900), returns the next earliest anniversary
- * that is after the current point in time (in the local time zone). Otherwise, returns the
- * adjusted Date in the local time zone.
- */
- public static Date getNextAnnualDate(Calendar target) {
- final Calendar today = Calendar.getInstance();
- today.setTime(new Date());
-
- // Round the current time to the exact start of today so that when we compare
- // today against the target date, both dates are set to exactly 0000H.
- today.set(Calendar.HOUR_OF_DAY, 0);
- today.set(Calendar.MINUTE, 0);
- today.set(Calendar.SECOND, 0);
- today.set(Calendar.MILLISECOND, 0);
-
- final boolean isYearSet = isYearSet(target);
- final int targetYear = target.get(Calendar.YEAR);
- final int targetMonth = target.get(Calendar.MONTH);
- final int targetDay = target.get(Calendar.DAY_OF_MONTH);
- final boolean isFeb29 = (targetMonth == Calendar.FEBRUARY && targetDay == 29);
- final GregorianCalendar anniversary = new GregorianCalendar();
- // Convert from the UTC date to the local date. Set the year to today's year if the
- // there is no provided year (targetYear < 1900)
- anniversary.set(!isYearSet ? today.get(Calendar.YEAR) : targetYear, targetMonth, targetDay);
- // If the anniversary's date is before the start of today and there is no year set,
- // increment the year by 1 so that the returned date is always equal to or greater than
- // today. If the day is a leap year, keep going until we get the next leap year anniversary
- // Otherwise if there is already a year set, simply return the exact date.
- if (!isYearSet) {
- int anniversaryYear = today.get(Calendar.YEAR);
- if (anniversary.before(today) || (isFeb29 && !anniversary.isLeapYear(anniversaryYear))) {
- // If the target date is not Feb 29, then set the anniversary to the next year.
- // Otherwise, keep going until we find the next leap year (this is not guaranteed
- // to be in 4 years time).
- do {
- anniversaryYear += 1;
- } while (isFeb29 && !anniversary.isLeapYear(anniversaryYear));
- anniversary.set(anniversaryYear, targetMonth, targetDay);
- }
- }
- return anniversary.getTime();
- }
-
/**
* Determine the difference, in days between two dates. Uses similar logic as the {@link
* android.text.format.DateUtils.getRelativeTimeSpanString} method.