This is an automated email from the ASF dual-hosted git repository.
bodewig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ant.git
The following commit(s) were added to refs/heads/master by this push:
new 4d1d05e98 use default timezone and locale in tstamp when
SOURCE_DATE_EPOCH is used
4d1d05e98 is described below
commit 4d1d05e989c0ffa493164ff9c4f2156676d1d773
Author: Stefan Bodewig <[email protected]>
AuthorDate: Sat Apr 11 15:01:47 2026 +0200
use default timezone and locale in tstamp when SOURCE_DATE_EPOCH is used
---
WHATSNEW | 11 ++++++
manual/Tasks/tstamp.html | 8 +++++
src/main/org/apache/tools/ant/taskdefs/Tstamp.java | 40 +++++++++++++++++++++-
3 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/WHATSNEW b/WHATSNEW
index 8bb2127b0..c6748d23f 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -1,6 +1,17 @@
Changes from Ant 1.10.17 TO Ant 1.10.18
=======================================
+Other changes:
+--------------
+
+ * when using the SOURCE_DATE_EPOCH environment variable to set the
+ time for <tstamp> the timezone will now be set to UTC for DSTAMP,
+ TSTAMP and TODAY. This also applies to nested formats where and
+ locale now also defaults to en_US unless it (or the timezone) have
+ been set explicitly.
+ Based on a patch used by the Debian Ant package maintainers.
+ Part of Bugzilla Report 61269
+
Changes from Ant 1.10.16 TO Ant 1.10.17
=======================================
diff --git a/manual/Tasks/tstamp.html b/manual/Tasks/tstamp.html
index c4183da25..3b1bf8c8f 100644
--- a/manual/Tasks/tstamp.html
+++ b/manual/Tasks/tstamp.html
@@ -51,6 +51,14 @@ <h3>Description</h3>
for that environment variable and will instead use the "current" date.
</p>
+<p>
+ <em>Since Ant 1.10.18</em> if the <code>SOURCE_DATE_EPOCH</code>
+ environment variable is used by the task, the timezone of DSTAMP,
+ TSTAMP and TODAY will be set to UTC. This is also true for nested
+ format elements where in addition the locale defaults to en_US
+ unless they are specified as part of the format element explicitly.
+</p>
+
<h3>Parameters</h3>
<table class="attr">
<tr>
diff --git a/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
b/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
index ca10efe00..d0b27ba2a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
@@ -51,6 +51,8 @@ import org.apache.tools.ant.types.EnumeratedAttribute;
public class Tstamp extends Task {
private static final String ENV_SOURCE_DATE_EPOCH = "SOURCE_DATE_EPOCH";
+ private static final TimeZone DEFAULT_TIME_ZONE =
TimeZone.getTimeZone("UTC");
+ private static final String DEFAULT_LOCALE = "en_US";
private List<CustomFormat> customFormats = new Vector<>();
private String prefix = "";
@@ -78,29 +80,42 @@ public class Tstamp extends Task {
try {
Date d = getNow();
// Honour reproducible builds
https://reproducible-builds.org/specs/source-date-epoch/#idm55
+ boolean reproducibleBuild = false;
final String epoch = System.getenv(ENV_SOURCE_DATE_EPOCH);
try {
if (epoch != null) {
// Value of SOURCE_DATE_EPOCH will be an integer,
representing seconds.
d = new Date(Long.parseLong(epoch) * 1000L);
log("Honouring environment variable " +
ENV_SOURCE_DATE_EPOCH + " which has been set to " + epoch);
+ reproducibleBuild = true;
}
} catch(NumberFormatException e) {
// ignore
log("Ignoring invalid value '" + epoch + "' for " +
ENV_SOURCE_DATE_EPOCH
+ " environment variable", Project.MSG_DEBUG);
}
+ final boolean reproducibleBuildRequested = reproducibleBuild;
final Date date = d;
- customFormats.forEach(cts -> cts.execute(getProject(), date,
getLocation()));
+ customFormats
+ .forEach(cts -> cts.execute(getProject(), date, getLocation(),
reproducibleBuildRequested));
SimpleDateFormat dstamp = new SimpleDateFormat("yyyyMMdd");
+ if (reproducibleBuildRequested) {
+ dstamp.setTimeZone(DEFAULT_TIME_ZONE);
+ }
setProperty("DSTAMP", dstamp.format(d));
SimpleDateFormat tstamp = new SimpleDateFormat("HHmm");
+ if (reproducibleBuildRequested) {
+ tstamp.setTimeZone(DEFAULT_TIME_ZONE);
+ }
setProperty("TSTAMP", tstamp.format(d));
SimpleDateFormat today
= new SimpleDateFormat("MMMM d yyyy", Locale.US);
+ if (reproducibleBuildRequested) {
+ today.setTimeZone(DEFAULT_TIME_ZONE);
+ }
setProperty("TODAY", today.format(d));
} catch (Exception e) {
@@ -325,6 +340,29 @@ public class Tstamp extends Task {
}
Tstamp.this.setProperty(propertyName, sdf.format(date));
}
+
+ /**
+ * validate parameter and execute the format.
+ * @param project project to set property in.
+ * @param date date to use as a starting point.
+ * @param location line in file (for errors)
+ * @param reproducibleBuildRequested whether reproducible
+ * builds are requestes - in which case defaults for timezone
+ * and locale may be applied
+ * @since Ant 1.10.18
+ */
+ public void execute(Project project, Date date, Location location,
+ boolean reproducibleBuildRequested) {
+ if (reproducibleBuildRequested) {
+ if (language == null) {
+ language = DEFAULT_LOCALE;
+ }
+ if (timeZone == null) {
+ timeZone = DEFAULT_TIME_ZONE;
+ }
+ }
+ execute(project, date, location);
+ }
}
/**