1

I am using the shell script to get current time of the build in Jenkins agent. This is being run in docker image node:alpine This command works:

def BUILDVERSION = sh(script: "echo `date +%Y-%m-%d-%H-%M-%S`", returnStdout: true).trim()
Output: 2021-11-20-15-27-57

Now I want to add 1 hour to the time value so I modified my script with -d '+1 hour' This shell script works in Linux in general, but if I use it on Jenkins build agent I am getting the message: invalid date '+1 hour' This is the script which does not work!

def BUILDVERSION = sh(script: "echo `date -d '+1 hour'  +%Y-%m-%d-%H-%M-%S`", returnStdout: true).trim()

Thanks for assistance!

vel
  • 1,000
  • 1
  • 13
  • 35
  • 1
    Perhaps due to this: "[_Runs a shell script (**defaults to sh**, but this is configurable) for building the project._](https://stackoverflow.com/a/12457930/1744774)". – Gerold Broser Nov 20 '21 at 18:58
  • @GeroldBroser I do not understand what you want to say...if you wanted to help..."sh" is being executed properly in my first script but it doesn't behave properly if I try to add `-d '+1 hour'` – vel Nov 20 '21 at 19:38
  • 1
    I thought of differences between `bash` and `sh` but thinking a second time about it that's not very likely for `date`. Perhaps you ran into [Jenkinsfile idiosynchrasies with escaping and quotes](https://gist.github.com/Faheetah/e11bd0315c34ed32e681616e41279ef4). Please add the relevant parts of the build's Console Output to your question. – Gerold Broser Nov 20 '21 at 20:03
  • 1
    @AndreyDonald why not [Use Groovy](https://stackoverflow.com/questions/40261710/getting-current-timestamp-in-inline-pipeline-script-using-pipeline-plugin-of-hud) for getting the time stamp? – Noam Helmer Nov 21 '21 at 10:53
  • @NoamHelmer thanks for the assistance. But can you help me how would I add 1 hour, since I do not need current time? `println now.format("yyMMdd.HHmm", TimeZone.getTimeZone('UTC'))` Thanks!!! – vel Nov 21 '21 at 12:23
  • 1
    There are multiples ways, the simplest one will probably be: `def now = new Date();` then `def inOneHour = new Date(now.getTime() + 1 * 3600 * 1000);` or alternatively `def inOneHour = new Date(now.getTime() + java.util.concurrent.TimeUnit.HOURS.toMillis(2));` and finally for the format: `println inOneHour.format("yyMMdd.HHmm", TimeZone.getTimeZone('UTC'))` – Noam Helmer Nov 21 '21 at 14:01
  • @NoamHelmer great! This works! if you wish you can put this as an asnwer... – vel Nov 21 '21 at 15:18

1 Answers1

3

Regarding the shell script you do not need the echo command as the output of the date command will be returned by the sh step, so the following should work:

def BUILDVERSION = sh(script: "date -d '+1 hour' +%Y-%m-%d-%H-%M-%S", returnStdout: true).trim()

Alternatively you can calculate your time stamp using Groovy (or Java) code which will probably make it easier to handle as part of the pipeline flow. You can use something like:

def HOUR = 3600 * 1000

def now = new Date();
def inOneHour = new Date(now.getTime() + 1 * HOUR);
println inOneHour.format("yyMMdd.HHmm", TimeZone.getTimeZone('UTC'))

Or by using TimeUnit.HOURS which requires an admin approval:

def now = new Date();
def inOneHour = new Date(now.getTime() + java.util.concurrent.TimeUnit.HOURS.toMillis(2));
println inOneHour.format("yyMMdd.HHmm", TimeZone.getTimeZone('UTC'))

The last option is to use the Groovy TimeCategory which provides a very friendly DSL syntax, but requires a @NonCPS attribute and should probably reside inside a shared library.
In the library it can look like:

import groovy.time.TimeCategory

@NonCPS
def addHoursToDate(Date date, Integer numOfHours) {
    use(TimeCategory) {
        return date + numOfHours.hours
    }
}
Noam Helmer
  • 5,310
  • 1
  • 9
  • 29