Adding support for (some of) ISO 8601 date formats
Bug: 3293435
Change-Id: I1925040b92895bc8c721f18d75f22329d0ba0ac8
diff --git a/src/com/android/contacts/editor/EventFieldEditorView.java b/src/com/android/contacts/editor/EventFieldEditorView.java
index 5a7fe36..eb75e5c 100644
--- a/src/com/android/contacts/editor/EventFieldEditorView.java
+++ b/src/com/android/contacts/editor/EventFieldEditorView.java
@@ -219,7 +219,11 @@
} else {
final ParsePosition position = new ParsePosition(0);
// Try parsing with year
- final Date date1 = kind.dateFormatWithYear.parse(oldValue, position);
+ Date date1 = kind.dateFormatWithYear.parse(oldValue, position);
+ if (date1 == null) {
+ // If that format does not fit, try guessing the right format
+ date1 = DateUtils.parseDate(oldValue);
+ }
if (date1 != null) {
calendar.setTime(date1);
oldYear = calendar.get(Calendar.YEAR);
diff --git a/src/com/android/contacts/util/DateUtils.java b/src/com/android/contacts/util/DateUtils.java
index eb33aaa..40570f0 100644
--- a/src/com/android/contacts/util/DateUtils.java
+++ b/src/com/android/contacts/util/DateUtils.java
@@ -32,11 +32,18 @@
public static final SimpleDateFormat DATE_AND_TIME_FORMAT =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+ // 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 = {
- NO_YEAR_DATE_FORMAT,
FULL_DATE_FORMAT,
DATE_AND_TIME_FORMAT,
+ new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"),
+ new SimpleDateFormat("yyyyMMdd"),
+ new SimpleDateFormat("yyyyMMdd'T'HHmmssSSS'Z'"),
+ new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'"),
+ new SimpleDateFormat("yyyyMMdd'T'HHmm'Z'"),
};
+
static {
for (SimpleDateFormat format : DATE_FORMATS) {
format.setLenient(true);
@@ -51,6 +58,25 @@
/**
* 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. Otherwise, returns
* the supplied string unchanged.
*/
@@ -66,20 +92,28 @@
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 date = f.parse(string, parsePosition);
+ date = f.parse(string, parsePosition);
if (parsePosition.getIndex() == string.length()) {
- java.text.DateFormat outFormat;
- if (f == NO_YEAR_DATE_FORMAT) {
- outFormat = isMonthBeforeDate(context) ? FORMAT_WITHOUT_YEAR_MONTH_FIRST
- : FORMAT_WITHOUT_YEAR_DATE_FIRST;
- } else {
- outFormat = DateFormat.getDateFormat(context);
- }
-
+ java.text.DateFormat outFormat = DateFormat.getDateFormat(context);
synchronized (outFormat) {
return outFormat.format(date);
}