DateUtils.java revision 2b3f95cc12b76523410782d4178562ce241410ef
145b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov/* 245b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project 345b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * 445b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); 545b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * you may not use this file except in compliance with the License. 645b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * You may obtain a copy of the License at 745b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * 845b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0 945b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * 1045b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * Unless required by applicable law or agreed to in writing, software 1145b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, 1245b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1345b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * See the License for the specific language governing permissions and 1445b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * limitations under the License. 1545b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov */ 1645b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 1745b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikovpackage com.android.contacts.util; 1845b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 1945b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikovimport android.content.Context; 2045b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikovimport android.text.format.DateFormat; 2145b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 2245b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikovimport java.text.ParsePosition; 2345b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikovimport java.text.SimpleDateFormat; 2445b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikovimport java.util.Date; 2545b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 2645b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov/** 2745b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * Utility methods for processing dates. 2845b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov */ 2945b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikovpublic class DateUtils { 30392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public static final SimpleDateFormat NO_YEAR_DATE_FORMAT = new SimpleDateFormat("--MM-dd"); 31392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public static final SimpleDateFormat FULL_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); 32392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public static final SimpleDateFormat DATE_AND_TIME_FORMAT = 33392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 3445b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 352b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov // Variations of ISO 8601 date format. Do not change the order - it does affect the 362b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov // result in ambiguous cases. 3745b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov private static final SimpleDateFormat[] DATE_FORMATS = { 38392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann FULL_DATE_FORMAT, 39392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann DATE_AND_TIME_FORMAT, 402b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"), 412b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov new SimpleDateFormat("yyyyMMdd"), 422b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov new SimpleDateFormat("yyyyMMdd'T'HHmmssSSS'Z'"), 432b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'"), 442b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov new SimpleDateFormat("yyyyMMdd'T'HHmm'Z'"), 4545b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov }; 462b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov 4745b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov static { 4845b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov for (SimpleDateFormat format : DATE_FORMATS) { 4945b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov format.setLenient(true); 5045b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 5145b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 5245b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 5345b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov private static final java.text.DateFormat FORMAT_WITHOUT_YEAR_MONTH_FIRST = 5445b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov new SimpleDateFormat("MMMM dd"); 5545b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 5645b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov private static final java.text.DateFormat FORMAT_WITHOUT_YEAR_DATE_FIRST = 5745b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov new SimpleDateFormat("dd MMMM"); 5845b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 5945b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov /** 6045b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * Parses the supplied string to see if it looks like a date. If so, 612b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov * returns the date. Otherwise, returns null. 622b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov */ 632b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov public static Date parseDate(String string) { 642b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov ParsePosition parsePosition = new ParsePosition(0); 652b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov for (int i = 0; i < DATE_FORMATS.length; i++) { 662b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov SimpleDateFormat f = DATE_FORMATS[i]; 672b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov synchronized (f) { 682b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov parsePosition.setIndex(0); 692b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov Date date = f.parse(string, parsePosition); 702b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov if (parsePosition.getIndex() == string.length()) { 712b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov return date; 722b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov } 732b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov } 742b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov } 752b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov return null; 762b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov } 772b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov 782b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov /** 792b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov * Parses the supplied string to see if it looks like a date. If so, 8045b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * returns the same date in a cleaned-up format. Otherwise, returns 8145b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov * the supplied string unchanged. 8245b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov */ 8345b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov public static String formatDate(Context context, String string) { 8445b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov if (string == null) { 8545b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov return null; 8645b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 8745b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 8845b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov string = string.trim(); 8945b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov if (string.length() == 0) { 9045b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov return string; 9145b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 9245b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 9345b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov ParsePosition parsePosition = new ParsePosition(0); 9445b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 952b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov Date date; 962b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov 972b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov synchronized (NO_YEAR_DATE_FORMAT) { 982b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov date = NO_YEAR_DATE_FORMAT.parse(string, parsePosition); 992b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov } 1002b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov 1012b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov if (parsePosition.getIndex() == string.length()) { 1022b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov java.text.DateFormat outFormat = isMonthBeforeDate(context) 1032b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov ? FORMAT_WITHOUT_YEAR_MONTH_FIRST 1042b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov : FORMAT_WITHOUT_YEAR_DATE_FIRST; 1052b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov synchronized (outFormat) { 1062b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov return outFormat.format(date); 1072b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov } 1082b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov } 1092b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov 11045b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov for (int i = 0; i < DATE_FORMATS.length; i++) { 11145b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov SimpleDateFormat f = DATE_FORMATS[i]; 11245b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov synchronized (f) { 11345b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov parsePosition.setIndex(0); 1142b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov date = f.parse(string, parsePosition); 11545b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov if (parsePosition.getIndex() == string.length()) { 1162b3f95cc12b76523410782d4178562ce241410efDmitri Plotnikov java.text.DateFormat outFormat = DateFormat.getDateFormat(context); 11745b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov synchronized (outFormat) { 11845b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov return outFormat.format(date); 11945b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 12045b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 12145b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 12245b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 12345b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov return string; 12445b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 12545b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov 12645b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov private static boolean isMonthBeforeDate(Context context) { 12745b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov char[] dateFormatOrder = DateFormat.getDateFormatOrder(context); 12845b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov for (int i = 0; i < dateFormatOrder.length; i++) { 12945b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov if (dateFormatOrder[i] == DateFormat.DATE) { 13045b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov return false; 13145b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 13245b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov if (dateFormatOrder[i] == DateFormat.MONTH) { 13345b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov return true; 13445b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 13545b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 13645b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov return false; 13745b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov } 13845b4402f0c05b21312dd8d647ae549d43057537dDmitri Plotnikov} 139