fix the patterns used by touch and date selectors

https://bz.apache.org/bugzilla/show_bug.cgi?id=59909
diff --git a/WHATSNEW b/WHATSNEW
index 9a36711..50128b8 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -40,6 +40,15 @@
    worked on OSes where sed is GNU sed.
    Bugzilla Report 59898
 
+ * <touch>'s default pattern as well as the default patterns used by
+   the <date> (resource) selectors depended on the JDK being used - or
+   rather the locale provider being used and the default locale
+   provider changed with Java 9.
+   They are now fixed and the documentation has been updated to
+   reflect the real patterns used rather than a non-formal description
+   of the expected format.
+   Bugzilla Report 59909
+
 Other changes:
 --------------
 
diff --git a/manual/Tasks/touch.html b/manual/Tasks/touch.html
index 263ea70..8adee38 100644
--- a/manual/Tasks/touch.html
+++ b/manual/Tasks/touch.html
@@ -74,8 +74,10 @@
   </tr>
   <tr>
     <td valign="top">pattern</td>
-    <td valign="top">SimpleDateFormat-compatible pattern string.
-       Defaults to MM/DD/YYYY HH:MM AM_or_PM or MM/DD/YYYY HH:MM:SS AM_or_PM.
+    <td valign="top">SimpleDateFormat-compatible pattern string using
+       the current locale.
+       Defaults to "MM/dd/YYYY hh:mm a" or "MM/dd/yyyy hh:mm:ss a"
+       using the US locale.
        <b>Since Ant 1.6.3</b></td>
     <td valign="top" align="center">No</td>
   </tr>
diff --git a/manual/Types/resources.html b/manual/Types/resources.html
index 58cefde..8ba77aa 100644
--- a/manual/Types/resources.html
+++ b/manual/Types/resources.html
@@ -641,9 +641,10 @@
     <tr>
       <td valign="top">pattern</td>
       <td valign="top">SimpleDateFormat-compatible pattern
-        for use with the <code>datetime</code> attribute</td>
+        for use with the <code>datetime</code> attribute using the
+        current locale</td>
       <td align="center" valign="top">
-        No, default is "MM/DD/YYYY HH:MM AM_or_PM"</td>
+        No, default is "MM/dd/yyyy hh:mm a" using the US locale</td>
     </tr>
     <tr>
       <td valign="top">granularity</td>
diff --git a/manual/Types/selectors.html b/manual/Types/selectors.html
index 560b416..402c711 100644
--- a/manual/Types/selectors.html
+++ b/manual/Types/selectors.html
@@ -173,9 +173,9 @@
       <tr>
         <td valign="top">datetime</td>
         <td valign="top">Specifies the date and time to test for.
-          Should be in the format MM/DD/YYYY HH:MM AM_or_PM, or
-          an alternative pattern specified via the <i>pattern</i>
-          attribute.
+          Should be in the format "MM/dd/yyyy hh:mm a" using the US
+          locale, or an alternative pattern specified via
+          the <i>pattern</i> attribute.
         </td>
         <td valign="top" align="center" rowspan="2">At least one of the two.</td>
       </tr>
@@ -212,7 +212,8 @@
       <tr>
         <td valign="top">pattern</td>
         <td valign="top">The <CODE>SimpleDateFormat</CODE>-compatible pattern
-          to use when interpreting the <i>datetime</i> attribute.
+          to use when interpreting the <i>datetime</i> attribute using
+          the current locale.
           <i>Since Ant 1.6.2</i>
         </td>
         <td valign="top" align="center">No</td>
diff --git a/src/main/org/apache/tools/ant/taskdefs/Touch.java b/src/main/org/apache/tools/ant/taskdefs/Touch.java
index 4a4118c..c6d79b7 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Touch.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Touch.java
@@ -61,23 +61,29 @@
 
     public static final DateFormatFactory DEFAULT_DF_FACTORY
         = new DateFormatFactory() {
-        /*
-         * The initial version used DateFormat.SHORT for the
-         * time format, which ignores seconds.  If we want
-         * seconds as well, we need DateFormat.MEDIUM, which
-         * in turn would break all old build files.
-         *
-         * First try to parse with DateFormat.SHORT and if
-         * that fails with MEDIUM - throw an exception if both
-         * fail.
-         */
+
+        private ThreadLocal<DateFormat> primary =
+            new ThreadLocal<DateFormat>() {
+                @Override
+                protected DateFormat initialValue() {
+                    return new SimpleDateFormat("MM/dd/yyyy hh:mm a",
+                                                Locale.US);
+                }
+            };
+        private ThreadLocal<DateFormat> fallback =
+            new ThreadLocal<DateFormat>() {
+                @Override
+                protected DateFormat initialValue() {
+                    return new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a",
+                                                Locale.US);
+                }
+            };
+
         public DateFormat getPrimaryFormat() {
-            return DateFormat.getDateTimeInstance(DateFormat.SHORT,
-                DateFormat.SHORT, Locale.US);
+            return primary.get();
         }
         public DateFormat getFallbackFormat() {
-            return DateFormat.getDateTimeInstance(DateFormat.SHORT,
-                DateFormat.MEDIUM, Locale.US);
+            return fallback.get();
         }
     };
     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
diff --git a/src/main/org/apache/tools/ant/types/resources/selectors/Date.java b/src/main/org/apache/tools/ant/types/resources/selectors/Date.java
index 8541e85..0719a18 100644
--- a/src/main/org/apache/tools/ant/types/resources/selectors/Date.java
+++ b/src/main/org/apache/tools/ant/types/resources/selectors/Date.java
@@ -137,10 +137,10 @@
             throw new BuildException(MILLIS_OR_DATETIME);
         }
         if (millis == null) {
-            DateFormat df = ((pattern == null)
-                ? DateFormat.getDateTimeInstance(
-                    DateFormat.SHORT, DateFormat.SHORT, Locale.US)
-                : new SimpleDateFormat(pattern));
+            String p = pattern == null ? "MM/dd/yyyy hh:mm a" : pattern;
+            DateFormat df = pattern == null
+                ? new SimpleDateFormat(p, Locale.US)
+                : new SimpleDateFormat(p);
             try {
                 long m = df.parse(dateTime).getTime();
                 if (m < 0) {
@@ -151,9 +151,8 @@
                 setMillis(m);
             } catch (ParseException pe) {
                 throw new BuildException("Date of " + dateTime
-                        + " Cannot be parsed correctly. It should be in"
-                        + (pattern == null
-                        ? " MM/DD/YYYY HH:MM AM_PM" : pattern) + " format.");
+                        + " Cannot be parsed correctly. It should be in '"
+                        + p + "' format.");
             }
         }
         return when.evaluate(r.getLastModified(), millis.longValue(), granularity);
diff --git a/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java b/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java
index 61d7a1a..414390e 100644
--- a/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java
@@ -34,7 +34,7 @@
 public abstract class BaseSelector extends DataType implements FileSelector {
 
     private String errmsg = null;
-
+    private Throwable cause;
 
     /**
      * Do nothing constructor.
@@ -55,6 +55,19 @@
     }
 
     /**
+     * Allows all selectors to indicate a setup error. Note that only
+     * the first error message is recorded.
+     *
+     * @param msg The error message any BuildException should throw.
+     */
+    public void setError(String msg, Throwable cause) {
+        if (errmsg == null) {
+            errmsg = msg;
+            this.cause = cause;
+        }
+    }
+
+    /**
      * Returns any error messages that have been set.
      *
      * @return the error condition
@@ -87,7 +100,7 @@
             verifySettings();
         }
         if (getError() != null) {
-            throw new BuildException(errmsg);
+            throw new BuildException(errmsg, cause);
         }
         if (!isReference()) {
             dieOnCircularReference();
diff --git a/src/main/org/apache/tools/ant/types/selectors/DateSelector.java b/src/main/org/apache/tools/ant/types/selectors/DateSelector.java
index aea94a8..8232e45 100644
--- a/src/main/org/apache/tools/ant/types/selectors/DateSelector.java
+++ b/src/main/org/apache/tools/ant/types/selectors/DateSelector.java
@@ -209,11 +209,10 @@
             setError("You must provide a datetime or the number of "
                     + "milliseconds.");
         } else if (millis < 0 && dateTime != null) {
-            // check millis and only set it once.
-            DateFormat df = ((pattern == null)
-                ? DateFormat.getDateTimeInstance(
-                    DateFormat.SHORT, DateFormat.SHORT, Locale.US)
-                : new SimpleDateFormat(pattern));
+            String p = pattern == null ? "MM/dd/yyyy hh:mm a" : pattern;
+            DateFormat df = pattern == null
+                ? new SimpleDateFormat(p, Locale.US)
+                : new SimpleDateFormat(p);
 
             try {
                 setMillis(df.parse(dateTime).getTime());
@@ -224,9 +223,8 @@
                 }
             } catch (ParseException pe) {
                 setError("Date of " + dateTime
-                        + " Cannot be parsed correctly. It should be in"
-                        + ((pattern == null)
-                        ? " MM/DD/YYYY HH:MM AM_PM" : pattern) + " format.");
+                        + " Cannot be parsed correctly. It should be in '"
+                         + p + "' format.", pe);
             }
         }
     }
diff --git a/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java b/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java
index 43278f4..7eb9501 100644
--- a/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java
+++ b/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java
@@ -73,7 +73,7 @@
         } catch (BuildException be3) {

             assertEquals("Date of this is not a date"

                         + " Cannot be parsed correctly. It should be in"

-                        + " MM/DD/YYYY HH:MM AM_PM format.", be3.getMessage());

+                        + " 'MM/dd/yyyy hh:mm a' format.", be3.getMessage());

         }

 

         s = new DateSelector();