Parse date string without losing timezone in Groovy for Jira - groovy

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

Related

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')
}

Inconsistent datetime object in Python3 and Django2

Python 3, Django 2
I am trying to get a function to consistently return a datetime object.
Here are the conditions where it does and does not work.
I have a function that generates a datetime object with an offset like so:
from django.conf import settings
from datetime import datetime
def off_time():
date = datetime.now()
offset = settings.TIME_OFFSET
offtime = date + offset
return offtime
TIME_OFFSET is generated in settings thus:
from datetime import timedelta
TIME_OFFSET = timedelta(days=370000)
If I save to a model object like this:
from django.db import models
import stellar.physics_tools
class Test(models.Model):
cdate = models.DateTimeField(default=stellar.physics_tools.off_time, help_text='When Generated')
and then work on the cdate, I can do this:
cdate = test.cdate
creation_date = cdate.strftime("%d-%m-%Y %H:%M:%S")
and it works ok.
but if I try this:
newtime = stellar.physics_tools.off_time
return newtime.strftime("%d-%m-%Y %H:%M:%S")
I get:
'function' object has no attribute 'strftime'
I need this function to return an object that I can use .strftime on, at least.
Any help appreciated. Thanks.
For this to work I need to call the function with () like this:
newtime = stellar.physics_tools.off_time()
I was not doing this because if I did this in the Django model construction it returns the value created when the class is defined, which is not what I want.
In short I still need to use stellar.physics_tools.off_time in the Django model, but when calling the function outside of this I need to use stellar.physics_tools.off_time().

Convert milliseconds to yyyy-MM-dd date-time format in Groovy

I am trying to convert milliseconds (e.g : 1503478800000) to yyyy-MM-ddTHH:mm:ss.SSS'Z' (e.g : 2017-08-23T09:00:000Z) date-time format.
Milliseconds value stored in the Soapui Global variable.
def testCase = messageExchange.modelItem.testCase;
def NewDateTime = testCase.testSuite.project.getPropertyValue("StartDateTime").toInteger();
log.info NewDateTime.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Error popup display :-
For input string: "1503478800000"
With Groovy you can do it with Date.format(String format) method, e.g.
def millis = testCase.testSuite.project.getPropertyValue("StartDateTime").toLong()
log.info new Date(millis).format("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")

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.

Date time in 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)

Resources