| @@ -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> | ||||