Jenkins Declarative Pipeline and Groovy ZonedDateTime for Regional Timestamp Conversion
0 reputation · 19 Mar 2022, 12:44 UTC
0 reputation · 19 Mar 2022, 12:44 UTC
In a Declarative Pipeline, I need to display the build start time in a specific regional time zone (e.g., America/New_York) for a report generated later in the pipeline.
The pipeline runs on agents with varying system time zones, and I want to avoid relying on the agent's local time; I prefer to use a pure Groovy solution within the pipeline script. I am unsure how to obtain the build timestamp as a ZonedDateTime and convert it to the desired zone without using external commands.
26525 reputation · 19 Mar 2022, 21:00 UTC
In a Declarative Pipeline you can read the build’s start time directly from the currentBuild object. The value currentBuild.startTimeInMillis is an epoch‑millisecond timestamp that is independent of the agent’s local clock. From that timestamp you can create a java.time.Instant and then apply any ZoneId you need.
def startMillis = currentBuild.startTimeInMillis
This returns the exact moment the build was queued, in UTC milliseconds since the epoch.
Instant or ZonedDateTimeimport java.time.*
import java.time.format.*
// Option A – keep it as an Instant
Instant buildInstant = Instant.ofEpochMilli(startMillis)
// Option B – immediately create a ZonedDateTime in the target zone
ZoneId targetZone = ZoneId.of('America/New_York')
ZonedDateTime buildInNY = buildInstant.atZone(targetZone)
String formatted = buildInNY.format(DateTimeFormatter.ofPattern('yyyy-MM-dd HH:mm:ss z'))
echo "Build started at ${formatted}"
The z pattern token includes the IANA zone abbreviation (e.g., "EDT" or "EST"). If you prefer the numeric offset, use XXX instead.
pipeline {
agent any
stages {
stage('Show Build Time') {
steps {
script {
import java.time.*
import java.time.format.*
def startMillis = currentBuild.startTimeInMillis
ZoneId nyZone = ZoneId.of('America/New_York')
ZonedDateTime startNY = Instant.ofEpochMilli(startMillis).atZone(nyZone)
String fmt = startNY.format(DateTimeFormatter.ofPattern('yyyy-MM-dd HH:mm:ss z'))
echo "Build started at ${fmt}"
}
}
}
}
}
java.time API is not available on older Java runtimes.America/New_York, Europe/London). An invalid ID throws an IllegalArgumentException.ZonedDateTime and Instant are serializable, you usually don’t need @NonCPS, but if you perform heavy processing inside a script block consider adding it to avoid CPS serialization issues.env.BUILD_START_NY = fmt
If you need a different target zone than the example, just replace ZoneId.of('America/New_York') with the desired IANA ID.
Use comments to ask for clarification. Post a solution as an answer.
26,525 reputation · 19 Mar 2022, 23:52 UTC
While the java.time approach is the standard for regional conversion, it is important to note that these methods often trigger RejectedAccessException errors in Jenkins Declarative Pipelines due to the Groovy Sandbox.
If you encounter security exceptions when calling ZoneId.of() or Instant.ofEpochMilli(), a Jenkins administrator must manually approve these signatures in Manage Jenkins > In-process Script Approval. To minimize the number of required approvals, you can wrap the logic in a Shared Library; methods executed within a trusted library bypass the sandbox restrictions, allowing the ZonedDateTime logic to run without individual signature approvals for every pipeline.