Insert Text Between Two Date Variables - linux

I am trying to insert some text between two date commands
Code:
date -u "+%H":00Z --date="1 hours ago" "+%a %b %d" --date="0 days ago"
Error:
date: extra operand ‘+%a %b %d’
Try 'date --help' for more information.
Expected Output:
11:00Z Fri Oct 20

With GNU date , in 2 steps:
date -d #$(date +%s --date="0 days ago") -u "+%H:00Z %a %b %d" --date="-1 hours ago"

Related

I have to extract the two epoch time from the data and then i have to find difference between them in bash?

I have this data where i have two epoch value and i have to extract the value and then need to calculate there difference?
;;epoch1;;epoch 2
617B96A302C71177;;1638297252.658;;1638297253.078;TTrans1;DEE61;66500;xxxxx;in;0x19;0x0;0;;scb:in;0x19;0x0;0;;sc:iund;0x0;ggp-ir:djkoe:ID 0: DSP: 1:trunk_02:ch_000
I tried below method but don't know how to calculate the difference.
#!/bin/bash
awk -F";;|;" -vOFS='\t' '{print strftime("%c", $3), strftime("%c", $2)}' duration.txt(data is written in this file)
Output of above command:-
Wed Dec 1 00:04:13 2021 Wed Dec 1 00:04:12 2021
Wed Dec 1 00:03:46 2021 Wed Dec 1 00:03:23 2021
epoch 1 =1638297252.658 epoch2 = 1638297253.078 first I have to extract the epochs value from the mentioned string. And then to calculate the time gap (or difference), I am trying to convert it into below format
Wednesday 01 December 2021 12:04:13 AM IST .
But even after converting both epoch in mentioned format i don't know what to do for calculating difference.
And I have used the awk command to extract the field from the string.
please excuse my poor explanation
awk -F ';' 'FNR!=1 {high = $3>$5?$3:$5; low = $3<$5?$3:$5; print high-low}' duration.txt
# gives
0.42
Or perhaps more readably:
awk -F ';' '
FNR!=1 {
if ($3 > $5) {
high=$3; low=$5
} else {
high=$5; low=$3
}
print high-low
}' duration.txt
Using awk
$ awk -F";" '{$3=strftime("%A %d %B %Y %T %Z",$3); $5=strftime("%A %d %B %Y %T %Z",$5); hour=substr($3,17,2);min=substr($3,20,2);sec=substr($3,23,2); hour2=substr($5,17,2);min2=substr($5,20,2);sec2=substr($5,23,2)} NR > 1 {print "epoch 1: "$3"\nepoch 2: "$5"\nTime difference is "hour2 - hour" hours " min2-min" minutes " sec2 - sec" seconds"}' input_file
epoch 1: Tuesday 30 November 2021 18:34:12 GMT
epoch 2: Tuesday 30 November 2021 18:34:13 GMT
Time difference is 0 hours 0 minutes 1 seconds
$ cat script.awk
#!/usr/bin/env/ awk -f
BEGIN {
FS=";"
} {
$3=strftime("%A %d %B %Y %T %Z",$3)
$5=strftime("%A %d %B %Y %T %Z",$5)
hour=substr($3,26,2)
min=substr($3,29,2)
sec=substr($3,32,2)
hour2=substr($5,26,2)
min2=substr($5,29,2)
sec2=substr($5,32,2)
} NR > 1 {
print "epoch 1: "$3"\nepoch 2: "$5"\nTime difference is "hour2 - hour" hours " min2-min" minutes " sec2 - sec" seconds"
}
$ awk -f script.awk input_file
epoch 1: Tuesday 30 November 2021 18:34:12 GMT
epoch 2: Tuesday 30 November 2021 18:34:13 GMT
Time difference is 0 hours 0 minutes 1 seconds

Converting date with timezone in UNIX timestamp Shell/Bash

I need to convert a date from string in the format "yyyy/mm/dd hh:mm:ss TZ" to UNIX time (TZ = Timezone).
What I have done so far is to convert a date in the format "yyyy/mm/dd hh:mm:ss" without a timezone to timestamp by using
dateYMD="2019/2/28 12:23:11.46"
newt=$(date -d "${dateYMD}" +"%s")
echo ${newt}
and I have the following result.
1551349391
My struggle is to find how both timezone and date/time can be converted to timestamp (unix time) . For example I need 4 variables with the same date/time as dateYMD but in 4 different timezones so that their timestamps would be different.
Here is the latest I have tried
dateYMD="2017/09/09 08:58:09"
timez=$(TZ=Australia/Sydney date -d #$(date +%s -d "${dateYMD}"))
unixTimez=$( date --date "${timez}" +"%s" )
echo ${unixTimez}
that showed me the following error
date: invalid date ‘чт фев 28 21:23:11 AEDT 2019’
You don't need to call date twice. Just call it once with TZ set to the timezone you want for that variable.
timesydney=$(TZ=Australia/Sydney date -d "$dateYMD" +%s)
timenyc=$(TZ=US/Eastern date -d "$dateYMD" +%s)
Either you do it by setting the TZ= environment variable (see answer of Barmar), or you include the time zone into the time string. This has higher priority than TZ=.
Examples:
TZ=UTC date -d '2019-01-01 12:00 CET' +'%s, %F %T %Z %z'
TZ=CET date -d '2019-01-01 12:00 CET' +'%s, %F %T %Z %z'
TZ=UTC date -d '2019-01-01 12:00 PDT' +'%s, %F %T %Z %z'
TZ=CET date -d '2019-01-01 12:00 PDT' +'%s, %F %T %Z %z'
TZ=UTC date -d '2019-01-01 12:00 +500' +'%s, %F %T %Z %z'
will print
1546340400, 2019-01-01 11:00:00 UTC +0000
1546340400, 2019-01-01 12:00:00 CET +0100
1546369200, 2019-01-01 19:00:00 UTC +0000
1546369200, 2019-01-01 20:00:00 CET +0100
1546326000, 2019-01-01 07:00:00 UTC +0000

With date, how to specify a relative date when the specified date contains hours/minutes/seconds

In Bash, I want to compute the sum of a date (reception date) and a relative duration (retention duration).
For example, let :
reception_date="2017-01-02 12:34:56"
retention_duration="+2 days"
I expect to have:
expiration_date="2017-01-04--12-34-56"
Please note that the retention duration could be any valid relative date recognize by date, like +X weeks or +X hours.
My first grasp of the date info page lead me to use date like this
$ date -d '2017-01-02 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-02--12-34-56
$ date -d '2017-01-02 12:34:56 +1 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--12-34-56
$ date -d '2017-01-02 12:34:56 +2 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--11-34-56
$ date -d '2017-01-02 12:34:56 +3 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--10-34-56
$ date -d '2017-01-02 12:34:56 +4 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--09-34-56
$ date -d '2017-01-02 12:34:56 +5 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--08-34-56
As you can see, it seems to work fine for the +1 days but I get really irregular results for higher values.
The following example work as expected but are far less readable:
$ date -d '2017-01-02 +1 days 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--12-34-56
$ date -d '2017-01-02 +2 days 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-04--12-34-56
$ date -d '2017-01-02 +3 days 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-05--12-34-56
$ date -d '+1 days 2017-01-02 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--12-34-56
$ date -d '+2 days 2017-01-02 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-04--12-34-56
$ date -d '+3 days 2017-01-02 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-05--12-34-56
In the ideal solution, I would like to have :
the correct expiration_date
the readable relative date format (to explain to the user how and why this expiration date was computed).
I don't want to play with seconds conversions and stuff like that, the human-level readability of the solution is mandatory.
Thanks !
More info:
I'm on a RedHat, with date version:
$ date --version
date (GNU coreutils) 8.4
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by David MacKenzie.
Revised answer
Following on from this downstream bug-report comment, I find you can do this by adding now:
$ date -d '2017-01-02 12:34:56 +2 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--05-34-56 ## Oops
$ date -d '2017-01-02 12:34:56 now +2 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-04--12-34-56 ## Much better
The now prevents date from parsing +2 as a timezone specification as well as a relative item. The difference between the two is explained in the docs, but the parser is apparently a bit odd in this situation. I think "now" also reads oddly from a human standpoint, but it could be worse!
To see what date is doing, add the --debug flag to your date command. See below for full explanation.
Original answer
At least as of now (and still as of date version 8.26), you have to put the relative time items somewhere other than after the times. The problem is that the + 1 hour is being interpreted both as a relative time and as a timezone (!!!!). The --debug flag to date is your friend.
Example of the right behavior (cygwin, date v8.26; my comments added):
$ date --debug -d '+1 hour 2017-01-19 12:34:56' ## Relative before the time
date: parsed relative part: +1 hour(s) ## OK
date: parsed date part: (Y-M-D) 2017-01-19
date: parsed time part: 12:34:56
date: input timezone: -05:00 (set from TZ="America/New_York" environment value) ## Also OK
date: using specified time as starting value: '12:34:56'
date: starting date/time: '(Y-M-D) 2017-01-19 12:34:56 TZ=-05:00'
date: '(Y-M-D) 2017-01-19 12:34:56 TZ=-05:00' = 1484847296 epoch-seconds
date: after time adjustment (+1 hours, +0 minutes, +0 seconds, +0 ns),
date: new time = 1484850896 epoch-seconds
date: output timezone: -05:00 (set from TZ="America/New_York" environment value) ## Still OK
date: final: 1484850896.000000000 (epoch-seconds)
date: final: (Y-M-D) 2017-01-19 18:34:56 (UTC0)
date: final: (Y-M-D) 2017-01-19 13:34:56 (output timezone TZ=-05:00)
Thu, Jan 19, 2017 1:34:56 PM ## A sensible result
Example of the wrong behavior:
$ date --debug -d '2017-01-19 12:34:56 + 1 hour' # +1 hour at the _end_
date: parsed date part: (Y-M-D) 2017-01-19
date: parsed time part: 12:34:56 TZ=+01:00 ## TZ=+1 oops!
date: parsed relative part: +1 hour(s) ## Parsed as a relative part also!
date: input timezone: +01:00 (set from parsed date/time string) ##Oops
date: using specified time as starting value: '12:34:56'
date: starting date/time: '(Y-M-D) 2017-01-19 12:34:56 TZ=+01:00' ##Oops
date: '(Y-M-D) 2017-01-19 12:34:56 TZ=+01:00' = 1484825696 epoch-seconds
date: after time adjustment (+1 hours, +0 minutes, +0 seconds, +0 ns),
date: new time = 1484829296 epoch-seconds
date: output timezone: -05:00 (set from TZ="America/New_York" environment value) ## That's OK
date: final: 1484829296.000000000 (epoch-seconds)
date: final: (Y-M-D) 2017-01-19 12:34:56 (UTC0)
date: final: (Y-M-D) 2017-01-19 07:34:56 (output timezone TZ=-05:00)
Thu, Jan 19, 2017 7:34:56 AM ## Bogus!
I am guessing that you are in a UTC+1 time zone, so date(1) interpreting +1 days as a UTC+1:00 timezone didn't hurt you. Edit This has been reported to gnulib but does not appear to have been patched, so you may just have to go with the workaround you have already hit on. The good news is that you do not have to present the same strings to users that you do to date. For example,
rel="+2 days"
base="$(date)"
exp="$(date -d "$rel $base")
echo "$base $rel is $exp"
Note the order of $base and $rel is swapped in the last two lines.
Another alternative, of course, is to switch everything to UTC so you can say date --debug -d '2017-01-19 12:34:56 Z + 1 hour' (with Z) to force the relative part to be interpreted as such.

Configuring date command to meet my format

I have a date in YYYY.MM.DD HH:SS format (e.g. 2014.02.14 13:30). I'd like to convert it in seconds since epoch using the date command.
The command
date -d"2014.02.14 13:30" +%s
won't work, because of the dots separation.
Any Ideas?
Why don't you make the date format acceptable? Just replace dots with dashes:
$ date --date="`echo '2014.02.14 13:30' | sed 's/\./-/g'`" +%s
1392370200
Here I first change the format:
$ echo '2014.02.14 13:30' | sed 's/\./-/g'
2014-02-14 13:30
and then use the result as a parameter for date.
Note that the result depends on your timezone.
You can use:
s='2014.02.14 13:30'
date -d "${s//./}"
Fri Feb 14 13:30:00 EST 2014
To get EPOCH value:
date -d "${s//./}" '+%s'
1392402600
using awk :
s=`echo "2014.02.14 13:30" | awk '{gsub(/\./,"-",$0);print $0}'`
echo -d "$s"
date -d "$s" +%s
output:
Fri Feb 14 13:30:00 IST 2014
1392364800
Perl: does not require you to munge the string
d="2014.02.14 13:30"
epoch_time=$(perl -MTime::Piece -E 'say Time::Piece->strptime(shift, "%Y.%m.%d %H:%M")->epoch' "$d")
echo $epoch_time
1392384600
Timezone: Canada/Eastern
I Finally solved it using
awk 'BEGIN{FS=","}{ gsub(/./," ",$1);gsub(/:/," ",$2); var=sprintf("%s %s 00",$1,$2); print mktime(var), $3,$4,$5,$6,$7 }' myfile | less
so myfile:
2014.09.24,15:15,1.27921,1.27933,1.279,1.27924,234
became
1411582500 1.27921 1.27933 1.279 1.27924 234
:)

The date command do not convert to time stamp the format returned by date command

the date command of linux return the following date format
root#root:~# date
Sat Jun 14 06:36:42 CEST 2014
The current date time stamp could be printed if I add +%s
root#root:~# date +%s
1402720624
Now If I want to print the time stamp of the date returned by the date command, I get the following error
root#Inteno:~# date -d"Sat Jun 14 06:36:42 CEST 2014" +%s
date: invalid date 'Sat Jun 14 06:36:42 CEST 2014'
How I can make the date return the time stamp of the date format Sat Jun 14 06:36:42 CEST 2014 ?
Note: I m using date from BusyBox v1.19.4
Unfortunately busybox's date has limitations but if you can consider using timestamps instead you can do:
TS=$(date '+%s')
date -d "#${TS}"
Still if CEST is your current local time, you can do:'
DATE=$(date)
date -d "$(echo "$DATE" | cut -d ' ' -f 2,3,4,6)" '+%s'
As removing the timezone would still apply.

Resources