I am trying to log the time between two events. No problems with minutes or seconds but the hour is off. Here is the code
def cur =new Date(now()-atomicState.lastTime).format('HH:mm:ss',location.timeZone)
msg="$msg Time Elapsed since last Event: $cur"
atomicState.lastTime=now()
The hour results are always off. If the event occurred during the same hour the results of the above will look similar to 19:14:20 the minute:second portion (14:20) is correct. If the event spans one or more hour the results will be similar to 20:02:01 The hour portion is at least 20.
If I change the above to
def cur =new Date(now()-atomicState.lastTime).format('mm:ss',location.timeZone)
msg="$msg Time Elapsed since last Event: $cur"
atomicState.lastTime=now()
The minutes:Seconds will always be correct but the event may have occurred several hours ago. For example
Event 1 at 12:15:30 PM
Event 2 at 4:45:45 PM
You are creating a Date that is X time after the epoch and then using format to convert to you current timezone, which probably is a few hours off of GMT.
Just to be clear, your problem is that you treat the difference between two dates as a new date. This only works in a small corner case where the difference is less than 24 hours and you happen to be in the GMT timezone. Anything outside of that will mess up.
As you get 19:mm:ss I’ll venture a guess and say you’re based in New York or thereabouts. What happens is that you get say a 5 seconds difference and wrongly turn that into a date. Since time 0(zero) in computers is 00:00:00 January 1. 1970 you get 00:00:05 January 1. 1970. But since you’re 5 hours behind GMT we subtract 5 hours from that and end up in 19:00:05 December 31. 1969.
I’d skip the date-formatting and stick with the milliseconds you get from now(), and then pretty-print it ala
secs = diff/1000; // Milliseconds to seconds
printf("%02d:%02d:02d", (int) (secs/3600), (int)(secs % 3600/60), (int)(secs % 60))
Still have to think about how to consider values above 25 hours unless you’re okay with 25:mm:ss etc
The divide by 1000 probably turned the integer milliseconds into a decimal seconds, try casting it to int and see what happens: def secs = (int) (now() / 1000)
Note I only have a couple of weeks with groovy myself, so don’t know all the idiosyncrasies.
Here’s how I solved this. YMMV depending on what you’re trying to accomplish.
This is from a Windows Server Monitor DTH I’m working on for myself.
vitals.Uptime could easily be your atomicState.lastTime variable, but make sure you write it as atomicState.lastTime.toDouble() so it’s properly converted.