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