Date time in Groovy - groovy

I'm looking to add 1 second to a datetime so I can test date based pagination. I'm hoping get a date from our API response, convert the date string into a date, then convert that into milliseconds, add a second and then convert back into a datestring and use it in my next API request. ( sound longwinded? It sure feels like it is!)
I'm having and issue when I try to parse a dateTime. The following code is throwing an error:
def c= new date().parse("yyyy-mm-ddThh:mm:ss",lastDate)
log.info "new formatt"+lastDate
log.info c.timeInMillis
Error:
groovy.lang.MissingMethodException: No signature of method: java.util.Date.parse() is applicable for argument types: (java.lang.String, groovy.util.slurpersupport.NodeChildren) values: [yyyy-mm-ddThh:mm:ss, 2007-01-26T00:00:00] Possible solutions: parse(java.lang.String), parse(java.lang.String, java.lang.String), wait(), clone(), any(), use(java.util.List, groovy.lang.Closure)
Any tips on how to achieve my goal? Or is it a dimwit approach?

Sounds like quite a round about way of adding a second. Why not just:
import groovy.time.TimeCategory
def lastDate = new Date()
use(TimeCategory) {
lastDate = lastDate + 1.second
}
For more flexible date string parsing, you might want to look at the JChronic java library. It can handle dates in many different formats and doesn't rely on having an exact template like the SimpleDateFormat class. Here's an example using both of these:
Date.metaClass.'static'.fromString = { str ->
com.mdimension.jchronic.Chronic.parse(str).beginCalendar.time
}
def lastDate = Date.fromString("2007-01-26T00:00:00")
use (TimeCategory) {
100.times {
runTest(lastDate)
lastDate = lastDate + 1.second
}
}

Probably the most consise, idiomatic groovy solution without dependencies:
Date.parse( "yyyy-MM-dd'T'HH:mm:ss", text ).with { new Date( time + 1000) }

A more generic Java solution is to use the Joda Time library.
//
// Dependencies
// ============
import org.joda.time.*
import org.joda.time.format.*
#Grapes([
#Grab(group='joda-time', module='joda-time', version='1.6.2')
])
//
// Main program
// ============
DateTimeFormatter psr = ISODateTimeFormat.dateTimeParser()
DateTimeFormatter fmt = ISODateTimeFormat.dateHourMinuteSecond()
DateTime inDate = psr.parseDateTime("2010-11-18T23:23:59")
println fmt.print(inDate.plusSeconds(1))
It can handle any incoming and outgoing date formatting, including complex scenarios with timezones in the Date string, eg "2010-11-18T23:23:59+01:00"

A colleague helped with the following -
--import groovy.time.TimeCategory)
def aDate = lastDate.toString()
def newdate = Date.parse("yyyy-MM-dd'T'HH:mm:ss",aDate)
use(TimeCategory){
newdate = newdate+1.second
}
I had a bit of difficulty initially adding the time - the types weren't playing nicely together.
Thanks all for your responses folks!

Take a look here:
http://groovy.codehaus.org/JN0545-Dates
You want to use something like:
def c = Calendar.instance
c.add(Calendar.SECOND, 1)
You need to initialize c with a date you want, look at the link on different possibilities, but here's an example:
c = new GregorianCalendar(2009, Calendar.JULY, 22, 2, 35, 21)

Related

Groovy script is not working in Jenkins Active choice parameter

I am working a groovy script which is working perfectly on the Jenkins Scriptler but when I tried to run the same script from active choice parameter, it is not returning any values.
Could someone help me on this?
import java.time.format.DateTimeFormatter
exception_file = "test/10-01-2023/test"
String ex_date = exception_file.split('/')[1].toString()
println ex_date
cDate = java.time.LocalDate.now()
currentDate = cDate.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))
expiry_date = Date.parse("dd-MM-yyyy", ex_date)
return expiry_date
But in parameters it is empty. AM i missing something?
I've reproduced the problem using your code. The only thing you are missing is the correct return type. It must be either java.util.List, Array, or java.util.Map.
In the following I'm returning an array.
import java.time.format.DateTimeFormatter
exception_file = "test/10-01-2023/test"
String ex_date = exception_file.split('/')[1].toString()
println ex_date
cDate = java.time.LocalDate.now()
currentDate = cDate.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))
expiry_date = Date.parse("dd-MM-yyyy", ex_date)
return [ expiry_date ]
This renders like:

Execute Groovy Script to transform date in Nifi

I'm trying to transform my JSON dates using Nifi. They are imported in this format:
import groovy.json.JsonSlurper
import groovy.json.JsonBuilder
def ff = session.get()
if(!ff)return
ff = session.write(ff, {rawIn, rawOut->
// transform streams into reader and writer
rawIn.withReader("UTF-8"){reader->
rawOut.withWriter("UTF-8"){writer->
//parse reader into Map
def json = new JsonSlurper().parse(reader)
// set my variable and define what format it is in
json.date = new Date(json.date as Long).format('HH:mm yyyy-MM-dd')
// Reformat it
json.date = DateFormat.parse("yyyy-MM-dd HH:mm", json.date)
//write changed object to writer
new JsonBuilder(json).writeTo(writer)
}
}
} as StreamCallback)
session.transfer(ff, REL_SUCCESS)
The incoming flowfile has this body:
[{"date":"09:00 2019-05-29","data":460.0,"name":"login"},{"date":"10:00 2019-05-29","data":548.0,"name":"login"},{"date":"11:00 2019-05-14","data":0.0,"name":"login"},{"date":"00:00 2019-06-15","data":0.0,"name":"login"}]
I want this output:
[{"date":"2019-05-29 09:00","data":460.0,"name":"login"},{"date":"2019-05-29 10:00","data":548.0,"name":"login"},{"date":"2019-05-14 11:00","data":0.0,"name":"login"},{"date":"2019-06-15 00:00","data":0.0,"name":"login"}]
The error I get is this:
Can anyone please help me understand where I am going wrong?
The input is a list of the objects in question. The incoming date is a
String -- not a Long.
So the first error is to use json.date as it implies json*.date
(which gives a list of all date).
Next casting the date to Long, create a new Date and then format it is
the wrong way around.
So to change the format of all the date something like this is needed:
json.each{
it.date = Date.parse('HH:mm yyyy-MM-dd', it.date).format('yyyy-MM-dd HH:mm')
}

Parse date string without losing timezone in Groovy for Jira

I have date strings being created with different timezones, and I need to display them in a different format, but still showing each one's original timezone.
I'm able to parse, but it parses to a unix timestamp, which then loses the original timezone.
def dateCreated = issue.fields.created
// 2018-12-21T10:20:00.483-0800
def dateParsed = Date.parse("yyyy-MM-dd'T'HH:mm:ss.SSSz", dateCreated)
// 1545416400483
def dateFormatted = dateParsed.format('yyyy-MM-dd h:mm a, z')
// 2018-12-21 6:20 PM, UTC
Is there a way to parse/format straight to the desired format without losing the timezone in the middle?
in java8 there are new classes to parse/format datetime:
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
def dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")
ZonedDateTime zdt = ZonedDateTime.parse('2018-12-21T10:20:00.483-0800',dtf)
println zdt.getZone()
and starting from groovy 2.5 this code could be minimized to
ZonedDateTime zdt = ZonedDateTime.parse('2018-12-21T10:20:00.483-0800',"yyyy-MM-dd'T'HH:mm:ss.SSSX")
println zdt.getZone()
Okay, I realized that this wouldn't actually get me what I want. The original string uses -0800, which is an offset, not a timezone. So I looked elsewhere in the API response and found the timezone of the person who created the issue. I used this to format the date properly.
Final code:
def dateCreated = issue.fields.created
// 2018-12-21T10:20:00.483-0800
def creatorTimeZone = issue.fields.creator.timeZone
// America/Los_Angeles
def dateParsed = Date.parse("yyyy-MM-dd'T'HH:mm:ss.SSSz", dateCreated)
// 1545416400483
def dateFormatted = dateParsed.format('yyyy-MM-dd h:mm a, z', TimeZone.getTimeZone(creatorTimeZone))
// 2018-12-21 10:20 AM, PST

How to add n minutes in groovy

I am working in SoapUI , which supports GroovyScript in TestCases.
In some TestCases i supposed to use a date of now + 15 minutes, 30, or 90 minutes.
If im using this script:
import java.util.Calendar;
def tdFormat = "yyyy-MM-dd HH:mm"
def today = Calendar.getInstance()
def today15min = today.add(today.MINUTE,15)
def todayFormated = today15min.format(tdFormat)
gets NullPointerException: Cannot invoke method format() on null object error at line: 6.
How can i fix this?
Using TimeCategory.
use( groovy.time.TimeCategory ) {
println 15.minutes.from.now.format( 'yyyy-MM-dd HH:mm' )
}
Calendar is a static class used to create Dates. Calendar.add() returns void, because it simply modifies the Calendar. You need to call getTime() to get a Date object which you can then format how you please.

Is there a way to declare a Groovy string format in a variable?

I currently have a fixed format for an asset management code, which uses the Groovy string format using the dollar sign:
def code = "ITN${departmentNumber}${randomString}"
Which will generate a code that looks like:
ITN120AHKXNMUHKL
However, I have a new requirement that the code format must be customizable. I'd like to expose this functionality by allowing the user to set a custom format string such as:
OCP${departmentNumber}XI${randomString}
PAN-${randomString}
Which will output:
OCP125XIBQHNKLAPICH
PAN-XJKLBPPJKLXHNJ
Which Groovy will then interpret and replace with the appropriate variable value. Is this possible, or do I have to manually parse the placeholders and manually do the string.replace?
I believe that GString lazy evaluation fits the bill:
deptNum = "C001"
randomStr = "wot"
def code = "ITN${deptNum}${->randomStr}"
assert code == "ITNC001wot"
randomStr = "qwop"
assert code == "ITNC001qwop"
I think the original poster wants to use a variable as the format string. The answer to this is that string interpolation only works if the format is a string literal. It seems it has to be translated to more low level String.format code at compile time. I ended up using sprintf
baseUrl is a String containing http://example.com/foo/%s/%s loaded from property file
def operation = "tickle"
def target = "dog"
def url = sprintf(baseUrl, operation, target)
url
===> http://example.com/foo/tickle/dog
I believe in this case you do not need to use lazy evaluation of GString, the normal String.format() of java would do the trick:
def format = 'ITN%sX%s'
def code = { def departmentNumber, def randomString -> String.format(format, departmentNumber, randomString) }
assert code('120AHK', 'NMUHKL') == 'ITN120AHKXNMUHKL'
format = 'OCP%sXI%s'
assert code('120AHK', 'NMUHKL') == 'OCP120AHKXINMUHKL'
Hope this helps.
for Triple double quoted string
def password = "30+"
def authRequestBody = """
<dto:authTokenRequestDto xmlns:dto="dto.client.auth.soft.com">
<login>support#soft.com</login>
<password>${password}</password>
</dto:authTokenRequestDto>
"""

Resources