/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.contacts.util; import android.content.Context; import android.text.format.DateFormat; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; 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"); // All the SimpleDateFormats in this class use the UTC timezone public static final SimpleDateFormat NO_YEAR_DATE_FORMAT = new SimpleDateFormat("--MM-dd", Locale.US); public static final SimpleDateFormat FULL_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.US); public static final SimpleDateFormat DATE_AND_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); public static final SimpleDateFormat NO_YEAR_DATE_AND_TIME_FORMAT = new SimpleDateFormat("--MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); // 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 = { FULL_DATE_FORMAT, 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), }; private static final java.text.DateFormat FORMAT_WITHOUT_YEAR_MONTH_FIRST = new SimpleDateFormat("MMMM dd"); private static final java.text.DateFormat FORMAT_WITHOUT_YEAR_DATE_FIRST = new SimpleDateFormat("dd MMMM"); static { for (SimpleDateFormat format : DATE_FORMATS) { format.setLenient(true); format.setTimeZone(UTC_TIMEZONE); } NO_YEAR_DATE_FORMAT.setTimeZone(UTC_TIMEZONE); FORMAT_WITHOUT_YEAR_MONTH_FIRST.setTimeZone(UTC_TIMEZONE); FORMAT_WITHOUT_YEAR_DATE_FIRST.setTimeZone(UTC_TIMEZONE); } /** * Parses the supplied string to see if it looks like a date. If so, * returns the date. Otherwise, returns null. */ public static Date parseDate(String string) { ParsePosition parsePosition = new ParsePosition(0); for (int i = 0; i < DATE_FORMATS.length; i++) { SimpleDateFormat f = DATE_FORMATS[i]; synchronized (f) { parsePosition.setIndex(0); Date date = f.parse(string, parsePosition); if (parsePosition.getIndex() == string.length()) { return date; } } } return null; } /** * Parses the supplied string to see if it looks like a date. If so, * returns the same date in a cleaned-up format for the user. Otherwise, returns * the supplied string unchanged. */ public static String formatDate(Context context, String string) { if (string == null) { return null; } string = string.trim(); if (string.length() == 0) { return string; } ParsePosition parsePosition = new ParsePosition(0); Date date; synchronized (NO_YEAR_DATE_FORMAT) { date = NO_YEAR_DATE_FORMAT.parse(string, parsePosition); } if (parsePosition.getIndex() == string.length()) { java.text.DateFormat outFormat = isMonthBeforeDate(context) ? FORMAT_WITHOUT_YEAR_MONTH_FIRST : FORMAT_WITHOUT_YEAR_DATE_FIRST; synchronized (outFormat) { return outFormat.format(date); } } 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()) { java.text.DateFormat outFormat = DateFormat.getDateFormat(context); outFormat.setTimeZone(UTC_TIMEZONE); return outFormat.format(date); } } } return string; } private static boolean isMonthBeforeDate(Context context) { char[] dateFormatOrder = DateFormat.getDateFormatOrder(context); for (int i = 0; i < dateFormatOrder.length; i++) { if (dateFormatOrder[i] == DateFormat.DATE) { return false; } if (dateFormatOrder[i] == DateFormat.MONTH) { return true; } } return false; } }