How to get difference between 2 dates (Z format) in milliseconds - linux

Well I'm trying to get the difference between two dates in Seconds.MilliSeconds The dates are in Zulu format
I have tried these two approaches doesn't work out for me
ms1=$(date -d '2022-04-22T03:47:56.744551446Z' +%N)
ms2=$(date -d '2022-04-22T03:47:57.095419744Z' +%N)
msdiff=$((ms1 - ms2))
echo "$msdiff"
$ dateutils.ddiff 2022-04-22T03:47:56.744551446Z 2022-04-22T03:47:57.095419744Z -f '%N'
0s
Is there any better way to get the difference in Seconds.MilliSeconds In linux for Z format time zones

Suggesting
ms1=$(date -d '2022-04-22T03:47:56.744551446Z' +%s.%N)
ms2=$(date -d '2022-04-22T03:47:57.095419744Z' +%s.%N)
msdiff=$(awk "BEGIN{print $ms2 - $ms1}")
echo "msdiff=$msdiff"
Output:
msdiff=0.350868

Related

Linux Date Function forward/backward time

Is there an option of date function?
How do I get LOAD_TEST_START to be 2 minutes forward?
How do I get LOAD_TEST_END to be 2 minutes back?
LOAD_TEST_START=$(date -u +%FT%TZ)
LOAD_TEST_END=$(date -u +%FT%TZ)
This answer helped me and works on the linux-version of date.
LOAD_TEST_START=$(date +%FT%TZ -d "2 minutes ago")
LOAD_TEST_END=$(date +%FT%TZ -d "2 minutes")
On macos/FreeBSD one can use
LOAD_TEST_START=$(date -v+2M +%FT%TZ)
LOAD_TEST_END=$(date -v-2M +%FT%TZ)
Not sure if this is what you want, but you can get the current epoch value and then add/subtract 120 seconds (2 minutes) from it and convert the results back to date.
dateval=`date +%s`
echo "orig "`date -d #$dateval +%FT%T%Z`
start=`expr $dateval + 120`
end=`expr $dateval - 120`
LOAD_TEST_START=`date -d #$start +%FT%T%Z`
LOAD_TEST_END=`date -d #$end +%FT%T%Z`
echo "start "$LOAD_TEST_START
echo "end "$LOAD_TEST_END

Calculate the 5 minutes ceiling

Operating System: Red Hat Enterprise Linux Server 7.2 (Maipo)
I want to round the time to the nearest 5 minutes, only up, not down, for example:
08:09:15 should be 08:10:00
08:11:26 should be 08:15:00
08:17:58 should be 08:20:00
I have been trying with:
(date -d #$(( (($(date +%s) + 150) / 300) * 300)) "+%H:%M:%S")
This will round the time but also down (08:11:18 will result in 08:10:00 and not 08:15:00)
Any idea how i can achieve this?
You may use this utility function for your rounding up:
roundDt() {
local n=300
local str="$1"
date -d #$(( ($(date -d "$str" '+%s') + $n)/$n * $n)) '+%H:%M:%S'
}
Then invoke this function as:
roundDt '08:09:15'
08:10:00
roundDt '08:11:26'
08:15:00
roundDt '08:17:58'
08:20:00
To trace how this function is computing use -x (trace mode) after exporting:
export -f roundDt
bash -cx "roundDt '08:11:26'"
+ roundDt 08:11:26
+ typeset n=300
+ typeset str=08:11:26
++ date -d 08:11:26 +%s
+ date -d #1535631300 +%H:%M:%S
08:15:00
GNU date can calculate already. It is explained in the manual in the chapter "Relative items in date strings". So you need just one date call.
d=$(date +%T) # get the current time
IFS=: read h m s <<< "$d" # parse it in hours, minutes and seconds
inc=$(( 300 - (m * 60 + s) % 300 )) # calculate the seconds to increment
date -d "$d $inc sec" +%T # output the new time with the offset
Btw: +%T is the same as +%H:%M:%S.

Assign variable inside for loop

I'm trying to do a simple for{} loop and I encountered problem with assign a variable inside loop. I will try to explain it on example:
DIFF=(`date +%s -d 20120203`-`date +%s -d 20120126`)/86400 # Difference between 2 dates.
echo $DIFF
end_date_change='20120126'
for i in {1..$DIFF} #Difference between 2 dates inside loop
do
end_date_change=$(end_date_change -d "-1 day") # Now, after every loop I would like to decrease date
echo $end_date_change
done
So the output should looks:
20120126
20120127
20120128
20120201
20120202
20120203
Anyone? Thanks in advance

How can you can calculate the time span between two time entries in a file using a shell script?

In a Linux script: I have a file that has two time entries for each message within the file. A 'received time' and a 'source time'. there are hundreds of messages within the file.
I want to calculate the elapsed time between the two times.
2014-07-16T18:40:48Z (received time)
2014-07-16T18:38:27Z (source time)
The source time is 3 lines after the received time, not that it matters.
info on the input data:
The input has a lines are as follows:
TimeStamp: 2014-07-16T18:40:48Z
2 lines later: a bunch of messages in one line and within each line, multiple times is:
sourceTimeStamp="2014-07-16T18:38:27Z"
If you have GNU's date (not busybox's), you can give difference in seconds with:
#!/bin/bash
A=$(date -d '2014-07-16T18:40:48Z' '+%s')
B=$(date -d '2014-07-16T18:38:27Z' '+%s')
echo "$(( A - B )) seconds"
For busybox's date and ash (modern probably / BusyBox v1.21.0):
#!/bin/ash
A=$(busybox date -d '2014-07-16 18:40:48' '+%s')
B=$(busybox date -d '2014-07-16 18:38:27' '+%s')
echo "$(( A - B )) seconds"
you should be able to use date like this (e.g.)
date +%s --date="2014-07-16T18:40:48Z"
to convert both timestamps into a unix timestamp. Getting the time difference between them is then reduced to a simple subtraction.
Does this help?
I would use awk. The following script searches for the lines of interest, converts the time value into a UNIX timestamp and saves them in the start, end variables. At the end of the script the difference will get calculated and printed:
timediff.awk:
/received time/ {
"date -d "$1" +%s" | getline end
}
/source time/ {
"date -d "$1" +%s" | getline start
exit
}
END {
printf "%s seconds in between", end - start
}
Execute it like this:
awk -f timediff.awk log.file
Output:
141 seconds in between

How to set timezone in gnuplot?

I have a simple gnuplot command file:
....
set xdata time
set timefmt "%s"
set format x "%H:%M"
....
where x - timestamp column.
Result - time in UTC format. Can I change local timezome for x axis ?
Just came across this in the docs today:
The conversion to and from seconds assumes Universal Time (which is the same
as Greenwich Standard Time). There is no provision for changing the time
zone or for daylight savings. If all your data refer to the same time zone
(and are all either daylight or standard) you don't need to worry about these
things. But if the absolute time is crucial for your application, you'll
need to convert to UT yourself.
From help time/date
I just ran across this today. You don't need to change the format, just change the data. If data.txt contains timestamps in UTC, and you want to display them in PDT (-7 hours off from UTC), simply use:
plot 'data.txt' using ($1+(-7*3600)):2
This subtracts 7 hours (in seconds) from each x value.
A bit late to the party, and I don't have enough reputation points to comment, but to add to anthony and hermannk's answer, this is how I implemented it with their information:
in command.gnuplot, assuming that the first field contains the date/time and the second field contains the value for the Y axis:
plot "inputfile" using ($1 - offset):2
from the (bash) command line, when invoking gnuplot:
gnuplot -e "offset=$(date +%s -d '1 Jan 1970')" command.gnuplot
The offset generally will work OK because gnuplot internally interprets date/time as seconds from epoch. I don't know if the form "offset=$(date ...)" is a bash specific thing, but you could always use "offset=`date ...`" instead.
EDIT --
I found this not to work very well when dealing with DST/Summer Time changes. I changed the offset calc to this, and now it works better:
in command.gnuplot, assuming that the first field contains the date/time and the second field contains the value for the Y axis:
plot "inputfile" using ($1 + offset):2
from the (bash) command line, when invoking gnuplot:
gnuplot -e "offset=$(echo "$(date +%z) * 36" | bc)" command.gnuplot
How does this work?
date +%z provides the timezone offset in the form -0400 or similar, which means Local_Time = UTC - 4 hours. If we consider this a number (-400), then the offset, in seconds, is -400 / 100 * 3600 = -400 * 36.
Note that this won't work with timezones that have 30 minutes increments (India?), but I'm sure with some creating math, you can cover that as well.
In addition to previous correct answer, there is how I do this under bash
From version 4.1 of bash, you could avoid using forks to date for this:
printf -v tzoff "%(%z)T" -1
tzoff=${tzoff:0:1}$(( ( 10#${tzoff:1:2}* 3600 + 10#${tzoff:3:2}* 60 ) ))
Some samples:
TZ=Asia/Katmandu printf -v tzoff "%(%z)T" -1
echo $tzoff
+0545
tzoff=${tzoff:0:1}$(( ( 10#${tzoff:1:2}* 3600 + 10#${tzoff:3:2}* 60 ) ))
echo $tzoff
+20700
TZ=America/Chihuahua printf -v tzoff "%(%z)T" -1
echo $tzoff
-0700
tzoff=${tzoff:0:1}$(( ( 10#${tzoff:1:2}* 3600 + 10#${tzoff:3:2}* 60 ) ))
echo $tzoff
-25200
Then alternatively add this $tzoff to values while creating .dat file or by adding them in plot command file.
printf -v plotcmd 'plot \47file.dat\47 using ($1%s):2' $tzoff
echo "$plotcmd"
plot 'file.dat' using ($1-25200):2
The snippet posted here did not work for me, but this seems to do the trick:
TZ=Europe/Amsterdam tzoff=$(printf "%(%z)T")
tzoff=${tzoff:0:1}$(( ( 10#${tzoff:1:2} * 3600 + 10#${tzoff:3:2}* 60 ) ))
echo $tzoff

Resources