Bash script/command to print out date 5 min before/after - bash

I need to somehow use the date command in bash or another utility to print out the date and time, 5 minutes before and 5 minutes after a given value.
For example:
input:
Thu Dec 19 14:10
output:
Thu Dec 19 14:05 Thu Dec 19 14:10 Thu Dec 19 14:15
I see that the date command can be used to do this on the current date/time, can it be used with a passed value, i.e. not the current date/time?

You can achieve this, for the current time, by typing.
$ date --date='5 minutes ago'; date; date --date='5 minutes'
Qui Dez 19 16:09:17 BRST 2013
Qui Dez 19 16:14:17 BRST 2013
Qui Dez 19 16:19:17 BRST 2013
To use a specific date (ex 1978/01/10).
$ date --date='1978-01-10 + 5 minutes'
Ter Jan 10 00:05:00 BRT 1978

With GNU date, you can do a simple form of date/time arithmetic with the argument to the --date option:
$ date --date 'now + 5 minutes'
With BSD date (at least, the version that ships with Mac OS X), the -v option allows you to do something similar:
$ date -v +5M
$ date -v -5M

If you're using bash under linux, you can use the -d parameter to perform date manipulation on an existing date:
Get the EPOCH time for the date in question:
EPOCH=$(date -d 'Thu Dec 19 14:10' '+%s')
This gives you the time, in seconds, since the EPOCH (typically 01/01/1970)
Now you can use simple math to subtract or add 5 minutes (in seconds) to the EPOCH time
NEW_EPOCH=$(($EPOCH - 300))
obviously, there are 300 seconds in 5 minutes
Now convert this NEW_EPOCH back into a human readable date
NEW_DATE=$(date -d "1970-01-01 ${NEW_EPOCH} sec")
NOTE that this only works on unix systems which support the date -d option (i.e. Linux)

If you want to do this for the current time +/-5 minutes and you use Bash 4.2 or newer, you can do it without external tools:
$ printf -v now '%(%s)T'
$ echo "$now"
1516161094
$ f='%a %b %d %R'
$ printf "%($f)T %($f)T %($f)T\n" "$((now-300))" "$now" "$((now+300))"
Tue Jan 16 22:46 Tue Jan 16 22:51 Tue Jan 16 22:56
The %(datefmt)T formatting string of printf allows to print date-time strings. If the argument is skipped (like here) or is -1, the current time is used.
%s formats the time in seconds since the epoch, and -v now stores the output in now instead of printing it.
f is just a convenience variable so I don't have to repeat the formatting string for the output three times.
Since the argument for this usage of printf has to be in seconds since the epoch, you're stuck with external tools to convert an input string like Thu Dec 19 14:10 into that format and you'd replace
printf -v now '%(%s)T'
with, for example, any of
now=$(date '+%s' -d 'Thu Dec 19 14:10') # GNU date
now=$(date -j -f '%a %b %d %T' 'Thu Dec 19 14:10' '+%s') # macOS date

Related

bash command to get current time in given time zone accounting for daylight savings

Is there a bash command that will tell me the current time in a given time zone while accounting for daylight savings? For example, I'm thinking of something like this:
$ getDateTime --region Seattle
2021-01-01-13-30-00
Importantly, I would like it to give me the standard time during the winter and daylight time during the summer, and switch over on the correct days of the year in accordance with the region. Does something like this exist in bash? If not, what about another language?
Set the TZ environment variable to the desired time zone and use the date command.
TZ=US/Pacific date
There are some city names in the timezone database, such as America/New_York and America/Los_Angeles, but it's not very complete and doesn't include Seattle. See https://data.iana.org/time-zones/tzdb-2019c/zone.tab for the master list.
Building on Barmar's answer, here's a bash function you can use:
getDateTime() {
TZ="$1" date '+%Y-%m-%d-%H-%M-%S %Z %z'
}
Sample usage:
getDateTime America/Los_Angeles
getDateTime America/New_York
getDateTime Pacific/Honolulu
getDateTime Asia/Hong_Kong
2022-07-08-18-06-50 PDT -0700
2022-07-08-21-06-50 EDT -0400
2022-07-08-15-06-50 HST -1000
2022-07-09-09-06-50 HKT +0800
Daylight savings times are handled automatically by the system, since the timezone names are timezone-aware.
Your system most likely uses the most up-to-date timezone information from IANA:
https://data.iana.org/time-zones/tzdb/zone.tab
https://ftp.iana.org/tz/tzdb/zone.tab
You can find your system's file of timezone names in:
/usr/share/zoneinfo/zoneinfo.tab
It seems like a really nice idea to map individual country/state/city names or latitude/longitude pairs to IANA timezone TZ names, there are probably third-party software out there that can do this.
Only with bash >= version 4.2:
TZ=US/Pacific printf -v unixtime "%(%Y-%m-%d-%H-%M-%S)T\n" -1
echo "$unixtime"
Output (e.g.)
2022-07-08-15-18-51
To demonstrate how the other answers work with DST:
"spring forward"
date:
$ TZ=America/Los_Angeles date -d '2022-03-13 01:59:59'
Sun Mar 13 01:59:59 PST 2022
$ TZ=America/Los_Angeles date -d '2022-03-13 + 1 second 01:59:59'
Sun Mar 13 03:00:00 PDT 2022
bash builtin printf
$ epoch=$(TZ=America/Los_Angeles date -d '2022-03-13 01:59:59' +%s)
$ TZ=America/Los_Angeles printf '%(%F %T %Z)T\n' $epoch
2022-03-13 01:59:59 PST
$ TZ=America/Los_Angeles printf '%(%F %T %Z)T\n' $((epoch + 1))
2022-03-13 03:00:00 PDT
"fall behind"
$ TZ=America/Los_Angeles date -d '2022-11-06 01:59:59'
Sun Nov 6 01:59:59 PDT 2022
$ TZ=America/Los_Angeles date -d '2022-11-06 + 1 second 01:59:59'
Sun Nov 6 01:00:00 PST 2022
$ epoch=$(TZ=America/Los_Angeles date -d '2022-11-06 01:59:59' +%s)
$ TZ=America/Los_Angeles printf '%(%F %T %Z)T\n' $epoch
2022-11-06 01:59:59 PDT
$ TZ=America/Los_Angeles printf '%(%F %T %Z)T\n' $((epoch + 1))
2022-11-06 01:00:00 PST

Shell Script to get date part from file and then compare it with last 2 days

I have a requirement where I need to extract the date part from a file name and then that date has to be compared with last 2 days and the date in file should not be older than 2 days.
For example I have a list of file names coming in a file like.
kuna_Project_10262017.txt
kuna_ProjectProfessional_10262017.txt
ffs_Programs_10_22_17_03_33.txt
I am extracting the date for first two with
row=($(awk -F '[_.]' '{print $3}' FFS_FILES.txt))
Row is a array containing the date part.
I am trying to use for loops to compare it.
But I am not able to compare the date after extraction with last 2 previous date as the format of input string is not the format it should expect, and also getting the date from the third file name is little strange.
Is there any way to solve it?
Here is sample script with comments.
CompareSec=$((60*60*24*2)); #number of seconds in two days
now=$(date "+%s" -d 'now'); #current time in seconds since EPOCH
while read file ; do
TimeStampRaw=$(echo "${file}" \
| sed 's/\([A-Z,a-z]*_[A-Z,a-z]*_[0-9]*_[0-9]*_\)\([0-9][0-9].*\)/\120\2/' \
| sed 's/[A-Z,a-z_.]//g' \
| sed 's/\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{4\}\)\(.*\)/\3\1\2 \4/')
# sed 's/\([A-Z,a-z]*_[A-Z,a-z]*_[0-9]*_[0-9]*_\)\([0-9][0-9].*\)/\120\2/'
# adds 20 before short format of year ( 17 -> 2017, 18 -> 2018 ) in files named ffs_Programs_10_22_17_03_33.txt
# sed 's/[A-Z,a-z_.]//g'
# delete any letters, dots and lines from text, leaving only numbers
# sed 's/\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{4\}\)\(.*\)/\3\1\2 \4/'
# puts Year at first, then month, day and optionaly time in format YYYYmmdd HHMM
TimeStampSec=$(date +%s -d "${TimeStampRaw}")
#file time in senconds since EPOCH
TimeStampHum=$(date -d "${TimeStampRaw}")
#file time in Human format
if [ $((${TimeStampSec} + ${CompareSec})) -ge ${now} ] ; then
echo "${file} is newer than ${CompareSec} Sec. (${TimeStampHum})"
else
echo "${file} is older than ${CompareSec} Sec. (${TimeStampHum})"
fi
done <1.txt
Contents of 1.txt:
$ cat 1.txt
kuna_Project_10262017.txt
kuna_ProjectProfessional_10262017.txt
ffs_Programs_10_22_17_03_33.txt
teSt_fiLe_05_07_18_03_33.txt
teSt_fiLe_05072018.txt
Output is:
kuna_Project_10262017.txt is older than 172800 Sec. (Thu Oct 26 00:00:00 MSK 2017)
kuna_ProjectProfessional_10262017.txt is older than 172800 Sec. (Thu Oct 26 00:00:00 MSK 2017)
ffs_Programs_10_22_17_03_33.txt is older than 172800 Sec. (Sun Oct 22 03:33:00 MSK 2017)
teSt_fiLe_05_07_18_03_33.txt is newer than 172800 Sec. (Mon May 7 03:33:00 MSK 2018)
teSt_fiLe_05072018.txt is newer than 172800 Sec. (Mon May 7 00:00:00 MSK 2018)

cutting out the hour part (not in 24 hour time) of a date?

My problem is with cutting the hour portion of the date out.
I am not allowed to use date commands only cut!!!!!
Suppose the date command at that time reads
Tues Apr 26 17:07:49 PDT 2017
then it should print out
5:07
I am having a lot of trouble because it is not recognizing a read on an int but rather a string. Been bugging me a long time now...
Here is my code thus far:
today=$(date)
echo The date right now is "$today"
echo "The time right now is $(printf '%s\n' "$today" | cut -c 11-19)"
let hour=${today:11:2}
let minute=${today:13:2}
if [[ ${hour} -ge 43200 ]]
then
let answer=hour-12
echo "The correct time is $answer:$minute pm"
fi
I calculated 43200 from the number of seconds at 12:00pm
Current output is:
The date right now is Wed Apr 26 21:47:39 PDT 2017
The time right now is 21:47:39
let hour=${today:11:2}
let minute=${today:13:2}
You have the following string format (with positions):
1 2
0123456789012345678901234567
Wed Apr 26 21:47:39 PDT 2017
^ ^
That means the two characters at offset 11 are 17 (correct) but the minute is being extracted at offset 13, which is :0. The correct extraction for minute would be ${today:14:2}.

Convert human readable time into EPOCH using shell script

I have a human readable time as
08-18-2016 09:18:25
I want it to be converted into epoch time using shell script.
I tried with date "+%s" but I am getting the error
date: invalid date `08-18-2016 09:32:42'
The canonical way to convert a datetime into epoch is to use:
date "+%s" # for this moment's date
date -d" some date" "+%s" # for a specific date
However, in this case the format is not valid:
$ date -d"08 18 2016 09:18:25" "+%s"
date: invalid date ‘08 18 2016 09:18:25’
You need, then, to massage the string a bit before passing it to date -d.
This converts the two first spaces into slashes:
$ sed 's# #/#;s# #/#' <<< "08 18 2016 09:18:25"
08/18/2016 09:18:25
So this works:
$ date -d"$(sed 's# #/#;s# #/#' <<< "08 18 2016 09:18:25")" "+%s"
1471504705
Or using variables:
$ nice_date=$(sed 's# #/#;s# #/#' <<< "08 18 2016 09:18:25")
$ date -d"$nice_date" "+%s"
1471504705
Thanks for the explanation fedorqui. But 1471511905 is the epoch time
for 08 18 2016 09:18:25, not 1471504705. – Mohit Rane
date -u … will print Coordinated Universal Time.

convert input timestamp from ist to utc (UNIX)

I am getting date as an input parameter which is IST from some source but I have to convert it into UTC format i.e., I have to substract 5 hours 30 minutes to the date which I am receiving.
echo "Date format DD/MM/YYYY HH:SS"
read $input
I can do this writing small function which will grep HH and SS from the $input and then add which checking conditions which is tedious task, instead I want to know is there any way to do this ?
I found date command option which works like this:
date -d "15/05/2014 10:12 -5 hours -30 minutes"
not working
date -d "15/05/2014 10:12 5 hours ago 30 minutes ago" also not working.
Assuming you are getting your IST date in $date variable you can do this to get GMT date:
date="15/05/2014 10:15"
As a 1st step convert your dd/mm/yyyy date to mm/dd/yyyy:
date=$(awk 'BEGIN{FS=OFS="/"} {print $2, $1, $3}' <<< "$date")
Convert to GMT:
( export TZ='GMT' && date -d 'TZ="Asia/Kolkata" '"$date" )
Thu May 15 04:45:00 GMT 2014
To get EPOCH GMT value:
( export TZ='GMT' && date -d 'TZ="Asia/Kolkata" '"$date" '+%s' )
1400129100

Resources