Groovy: Date and Time comparisons with a slight delay - datetime

So I have the following script:
import groovy.time.TimeCategory
def dueDate = context.expand( '${Test 4 - create user task#Response#$[\'_embedded\'][\'userTaskDtoList\'][0][\'dueDate\']}' )
def date = new Date(messageExchange.getTimestamp())
use(groovy.time.TimeCategory){
after24Hours = (date + 24.hours).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone('UTC')) }
assert dueDate == after24Hours
What I'm trying to do with this is take the date and time from a REST request (dueDate - which comes in UTC format and with a 24h delay) and create a new date and time from the timestamp of the moment when that request has been sent, which is registered from my system. I then convert that time to UTC to accommodate the format from dueDate and add 24h to it. At the end I verify that the date and time from dueDate and after24Hours is the same.
The output does return the same time but in certain cases if there is a delay between the time the request is being sent and the time is received then the assertion will fail. This depends on the server, usually there is a difference of like 1 millisecond but I'm thinking that if the server will be slower at some point this will definitely be bigger.
What could I do to allow some margin of error in the assertion, maybe like a few seconds or even a couple of minutes?
Ok, so I managed to do this:
import groovy.time.*
def dueDate = context.expand( '${Test 4 - create user task#Response#$[\'_embedded\'][\'userTaskDtoList\'][0][\'dueDate\']}' )
def date = new Date(messageExchange.getTimestamp())
use(groovy.time.TimeCategory){
after24Hours = (date + 24.hours).format("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone('UTC'))
def date1 = Date.parse("yyyy-MM-dd'T'HH:mm:ss'Z'", dueDate)
def date2 = Date.parse("yyyy-MM-dd'T'HH:mm:ss'Z'", after24Hours)
TimeDuration difference = TimeCategory.minus(date2, date1)
log.info date1
log.info date2
assert difference < 2.minutes
}
The script seems to work and it does return an error only if the time is longer than the one I've set in the assertion.
Unfortunately I have another issue now.
For some reason, my date output looks like this:
Fri Oct 01 16:24:10 EEST 2021: INFO: Sat Oct 02 13:24:10 EEST 2021
Which is not the correct format. That date should appear in the Zulu format, after all when I parsed the dates that was the format that I used.
Am I missing something?

What could I do to allow some margin of error in the assertion, maybe
like a few seconds or even a couple of minutes?
Instead of asserting that they are equal, you could assert that the difference between them is less than a threshold that you get to define.

If you use something like AssertJ, and I'd recommend you do, then you can do something like the following:
assertThat(dueDate).isCloseTo(after24Hours, within(1, ChronoUnit.MINUTE));
This will give a small margin to the comparison of the dates, and should fix your issue.

Related

Round back to quarter-hour in Mulesoft Dataweave

I have a Mule Server 4.3.0 EE application, and in it I want to round a DateTime to its most recent quarter-hour, with the result also being a DateTime. Some examples:
if the input is 9:18:32 AM, then the output is 9:15:00 AM the same day
if the input is 9:33:33 AM, then the output is 9:30:00 AM the same day
if the input is 9:59:58 AM, then the output is 9:45:00 AM the same day
if the input is 10:00:00 AM, then the output is 10:00:00 AM the same day
In this application, the input will always be in New York time, with DST in effect or not depending on the time of year.
Here's what I've come up with so far. Keep the date and hour, truncate the minutes to the nearest 15, set the seconds to zero, and keep the time zone. (There's a special case for '00' minutes because it won't convert if the minutes are a single '0'.)
I know newer Mule versions have the Dates package which would make this much more elegant, but upgrading isn't currently an option for me. Is this about as good as the code can be for those requirements, or is there a better way to do this without upgrading Mule? Thank you.
%dw 2.0
import * from dw::core::Strings
output application/json
fun roundBack(inputTime: DateTime): DateTime =
(inputTime[0 to 13] ++
(if (inputTime.minutes < 15) '00' else (inputTime.minutes - mod(inputTime.minutes, 15) as String)) ++
':00' ++
inputTime[-6 to -1]
) as DateTime
I believe that the logic is good but the implementation is fragile because it depends on auto coercions (DateTime to Strings when using the range selector []). It is better for me to be explicit in the conversions to avoid issues caused by unexpected defaults formats and warnings in the editor:
%dw 2.0
import * from dw::core::Strings
output application/json
fun roundBack(inputTime: DateTime): DateTime =
(
inputTime as String {format: "yyyy-MM-dd HH:"}
++ (if (inputTime.minutes < 15)
'00'
else (inputTime.minutes - mod(inputTime.minutes, 15)) as String
)
++':00'
++ inputTime as String {format: "xxx"}
) as DateTime {format: "yyyy-MM-dd HH:mm:ssxxx"}
---
roundBack(|2020-10-01T23:57:59-04:00|)
Output: "2020-10-01 23:45:00-04:00"

How to set different time slots for a single https requests in jmeter

I have a http request where I need to send random time values in given time frame
Request looks like this:
http://domain/api1?&mt=getEmp&punchTime=1590678744
I've shifts pre-defined
Morning: 0900 to 1400
Evening: 1400 to 1900
Night: 1900 to 2300
Expectation is: random epoch time value between pre-defined shift time slot should be put as punch-time for each request.
I don't want to separate out the request as per different time shifts.
Could anyone please help me to achieve this with JMeter?
You can calculate the random time stamp in the given range using a suitable JSR223 Test Element and Groovy language.
Example code which produces random time between 9 and 14 hour of the current day and store it into randomMorningTime JMeter Variable would be something like:
def calendar = Calendar.getInstance()
def morningStart = new GregorianCalendar(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 9, 00).getTimeInMillis()
def morningEnd = new GregorianCalendar(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 14, 00).getTimeInMillis()
def randomMorningTime = org.apache.commons.lang3.RandomUtils.nextLong(morningStart, morningEnd)
def timestamp = ( randomMorningTime / 1000).round() as String
log.info('Random morning time for current day: ' + new Date(randomMorningTime))
log.info('Associated timestamp: ' + timestamp)
vars.put('randomMorningTime', timestamp)
Demo:
You will be able to access the generated value as ${randomMorningTime} where required.
See JavaDoc on GregorianCalendar class for more information

moment toISOstring without modifying date

I have a date like "Thu Sep 01 2016 00:00:00 GMT+0530 (IST)" which I need to send to server as ISO-8601 utc time. I tried like :
moment(mydate).toISOString()
moment.utc(mydate).toISOString()
moment(mydate).utcOffset("+00:00").toISOString()
but I am getting the result like
2016-08-31T18:30:00.000Z
which is 1day behind my intended time. So what can I do to make moment ignore my local timezone and see it as UTC?
Edit:
The expected output is
2016-09-01T18:30:00.000Z
And no, the initial input isn't a string rather a javascript "new Date()" value.
Reason this happens:
This happens because .toISOString() returns a timestamp in UTC, even if the moment in question is in local mode. This is done to provide consistency with the specification for native JavaScript Date .toISOString()
Solution:
Use the same function and pass true value to it. This will prevent UTC Conversion.
moment(date).toISOString(true)
const date = new Date("2020-12-17T03:24:00");
const dateISOStringUTC = moment(date).toISOString();
const dateISOString = moment(date).toISOString(true);
console.log("Converted to UTC:" + dateISOStringUTC)
console.log("Actual Date value:" + dateISOString)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
I take the same problem today and find the solution.
Here is the solution: moment(date,moment.ISO_8601)
var date = new Date();
console.log("Original Date");
console.log(date);
console.log("After Moment Format");
console.log(moment(date,moment.ISO_8601));
Test Execution:
Moment Documentation: MomentJs

Wrong time difference with momentjs diff function

i'm trying to calculate the difference between two UTC Datetime Strings with angular-momentjs like shown below:
var start = "1970-01-01T11:03:00.000Z";
var end = "1970-01-01T11:15:00.000Z";
var duration = $moment.utc($moment(end).diff($moment(start))).format("hh:mm");
when i execute the code above, the duration should be 00:12 but actually it is 12:12. I don't understand why and how to fix it.
You are actually creating a moment.js object for 1970-01-01T00:12:00.000Z, then getting the time as hour and minutes. The token "hh" is for 12 hour time, so you're seeing "12" for 12am. If you want to see 00:12, use the token "HH" which gives 24 hour time: 00:12.

Groovy - idiomatic way of coding The Last Weekday - First of Month

What is the Groovy idiomatic way of asking for the last past weekday (ex. Monday)?
(or current week, the first day of the week)?
Also is there something similar for asking for the current month, the first of month?
static Date firstDayInWeek(Date day) {
day.clearTime()
return day - day.calendarDate.dayOfWeek
}
A year ago, I wrote a simple DSL for calculating dates, this allows you to do:
def mondayInJuly = new DateDSL().with {
first.monday.in.july( 2011 )
}
which sets mondayInJuly to be a Date object representing
Mon Jul 04 00:00:00 UTC 2011
I need to update the script to allow you to use Groovy 1.8's more lenient parser
As you mention DateTime in tags, I suggest JodaTime is OK. So, we do:
def lastMonday =
new DateTime().withDayOfWeek(DateTimeConstants.MONDAY).minusWeeks(1)
def firstThisMoth = new DateTime().withDayOfMonth(1)

Resources