@@ -40,6 +40,7 @@ import org.apache.tools.ant.types.resources.FileProvider; | |||||
import org.apache.tools.ant.types.resources.FileResource; | import org.apache.tools.ant.types.resources.FileResource; | ||||
import org.apache.tools.ant.types.resources.Touchable; | import org.apache.tools.ant.types.resources.Touchable; | ||||
import org.apache.tools.ant.types.resources.Union; | import org.apache.tools.ant.types.resources.Union; | ||||
import org.apache.tools.ant.util.DateUtils; | |||||
import org.apache.tools.ant.util.FileNameMapper; | import org.apache.tools.ant.util.FileNameMapper; | ||||
import org.apache.tools.ant.util.FileUtils; | import org.apache.tools.ant.util.FileUtils; | ||||
@@ -60,33 +61,20 @@ public class Touch extends Task { | |||||
DateFormat getFallbackFormat(); | DateFormat getFallbackFormat(); | ||||
} | } | ||||
/** | |||||
* Provides access to DateUtils.EN_US_DATE_FORMAT_MIN (primary) and | |||||
* DateUtils.EN_US_DATE_FORMAT_SEC (fallback). | |||||
*/ | |||||
public static final DateFormatFactory DEFAULT_DF_FACTORY | public static final DateFormatFactory DEFAULT_DF_FACTORY | ||||
= new DateFormatFactory() { | = new DateFormatFactory() { | ||||
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); | |||||
} | |||||
}; | |||||
@Override | @Override | ||||
public DateFormat getPrimaryFormat() { | public DateFormat getPrimaryFormat() { | ||||
return primary.get(); | |||||
return DateUtils.EN_US_DATE_FORMAT_MIN.get(); | |||||
} | } | ||||
@Override | @Override | ||||
public DateFormat getFallbackFormat() { | public DateFormat getFallbackFormat() { | ||||
return fallback.get(); | |||||
return DateUtils.EN_US_DATE_FORMAT_SEC.get(); | |||||
} | } | ||||
}; | }; | ||||
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | ||||
@@ -29,8 +29,6 @@ import java.util.TimeZone; | |||||
import java.util.regex.Matcher; | import java.util.regex.Matcher; | ||||
import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||
import org.apache.tools.ant.taskdefs.Touch; | |||||
/** | /** | ||||
* Helper methods to deal with date/time formatting with a specific | * Helper methods to deal with date/time formatting with a specific | ||||
* defined format (<a href="http://www.w3.org/TR/NOTE-datetime">ISO8601</a>) | * defined format (<a href="http://www.w3.org/TR/NOTE-datetime">ISO8601</a>) | ||||
@@ -93,6 +91,32 @@ public final class DateUtils { | |||||
private static final ChoiceFormat SECONDS_FORMAT = | private static final ChoiceFormat SECONDS_FORMAT = | ||||
new ChoiceFormat(LIMITS, SECONDS_PART); | new ChoiceFormat(LIMITS, SECONDS_PART); | ||||
/** | |||||
* Provides a thread-local US-style date format. Exactly as used by | |||||
* {@code <touch>}, to minute precision: | |||||
* {@code SimpleDateFormat("MM/dd/yyyy hh:mm a", Locale.US)} | |||||
*/ | |||||
public static final ThreadLocal<DateFormat> EN_US_DATE_FORMAT_MIN = | |||||
new ThreadLocal<DateFormat>() { | |||||
@Override | |||||
protected DateFormat initialValue() { | |||||
return new SimpleDateFormat("MM/dd/yyyy hh:mm a", Locale.US); | |||||
} | |||||
}; | |||||
/** | |||||
* Provides a thread-local US-style date format. Exactly as used by | |||||
* {@code <touch>}, to second precision: | |||||
* {@code SimpleDateFormat("MM/dd/yyyy hh:mm:ss a", Locale.US)} | |||||
*/ | |||||
public static final ThreadLocal<DateFormat> EN_US_DATE_FORMAT_SEC = | |||||
new ThreadLocal<DateFormat>() { | |||||
@Override | |||||
protected DateFormat initialValue() { | |||||
return new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a", Locale.US); | |||||
} | |||||
}; | |||||
static { | static { | ||||
MINUTE_SECONDS.setFormat(0, MINUTES_FORMAT); | MINUTE_SECONDS.setFormat(0, MINUTES_FORMAT); | ||||
MINUTE_SECONDS.setFormat(1, SECONDS_FORMAT); | MINUTE_SECONDS.setFormat(1, SECONDS_FORMAT); | ||||
@@ -332,11 +356,11 @@ public final class DateUtils { | |||||
} catch (NumberFormatException nfe) {} | } catch (NumberFormatException nfe) {} | ||||
try { | try { | ||||
return Touch.DEFAULT_DF_FACTORY.getPrimaryFormat().parse(dateStr); | |||||
return EN_US_DATE_FORMAT_MIN.get().parse(dateStr); | |||||
} catch (ParseException pe) {} | } catch (ParseException pe) {} | ||||
try { | try { | ||||
return Touch.DEFAULT_DF_FACTORY.getFallbackFormat().parse(dateStr); | |||||
return EN_US_DATE_FORMAT_SEC.get().parse(dateStr); | |||||
} catch (ParseException pe) {} | } catch (ParseException pe) {} | ||||
Matcher m = iso8601normalizer.matcher(dateStr); | Matcher m = iso8601normalizer.matcher(dateStr); | ||||
@@ -182,4 +182,24 @@ | |||||
<fileset dir="${basedir}" includes="zip-test.xml"/> | <fileset dir="${basedir}" includes="zip-test.xml"/> | ||||
</zip> | </zip> | ||||
</target> | </target> | ||||
<target name="testSetZipModTime"> | |||||
<mkdir dir="${input}/"/> | |||||
<touch file="${input}/test1.txt"/> | |||||
<mkdir dir="${output}"/> | |||||
<zip destfile="${output}/test.zip" basedir="${input}" modificationtime="2016-01-01 00:00"> | |||||
<fileset dir="${input}"/> | |||||
</zip> | |||||
<checksum file="${output}/test.zip" property="testSetZipModTime_hash" /> | |||||
<delete file="${output}/test.zip" /> | |||||
<touch file="${input}/test1.txt"/> | |||||
<zip destfile="${output}/test.zip" basedir="${input}" modificationtime="2016-01-01 00:00"> | |||||
<fileset dir="${input}"/> | |||||
</zip> | |||||
<checksum file="${output}/test.zip" property="testSetZipModTime_hash" verifyproperty="testSetZipModTime_okay" /> | |||||
<au:assertTrue> | |||||
<equals arg1="${testSetZipModTime_okay}" arg2="true" /> | |||||
</au:assertTrue> | |||||
</target> | |||||
</project> | </project> |