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);
                     }