How to subtract 5 minute from date - bash

I have this data:
`date +%Y-%m-%d`" 00:00:00"
that return 2015-10-08 00:00:00
I would like cancel 5 minute:
2015-10-07 23:55:00
Many thanks

You need to subtract 5 minutes from a known point in time:
$ date -d "00:00:00 today"
Thu Oct 8 00:00:00 EDT 2015
$ date -d "00:00:00 today -5 minutes"
Wed Oct 7 23:55:00 EDT 2015
You just need to add your format string.

There's more than one way to subtract a value from the current time, although this should match the format shown in your question:
date -d "-5 min" "+%Y-%m-%d %H:%M:%S"
Result:
2015-10-08 15:26:13

Related

Subtract hours from date object in bash

I need to find a time X hours before the previous midnight, thus I would like to subtract X hours from a date object.
Example
# Finding the previous midnight
date -d "yesterday 23:59:59"
Mon Jul 11 00:00:00 CEST 2022
What I want
I would like to find the date X hours before this midnight
x=4
Mon Jul 10 20:00:00 CEST 2022
You can use this date command:
date -d "today 0 -4 hours"
Here:
today 0: gets midnight date-time for today's date
-4 hours: subtracts 4 hours from midnight time
It seems one can just write the following:
date --date 'yesterday 23:59:59 CEST -4 hours'

How to convert a timestamp to a different timezone in bash?

I have a time in GMT, that looks like this:
Wed Feb 13 04:46:54 +0000 2019
In a bash script on MacOS 10.14.3, I want to convert it to the user's local timezone. i.e., this one is 04, so changing it to my timezone would be -6, so it would end up something like this:
Tue Feb 12 22:46:54 CST 2019
Thanks in advance.
Is this what you are looking for ?
date -d "Wed Feb 13 04:46:54 +0000 2019 - 6 hour"
dt= "Wed Feb 13 04:46:54 +0000 2019"
tz="-6"
date -d "$dt $tz hour"
I ended up using something like this:
postYear=`TZ="${timeZone}" date -jf "%Y-%m-%d %H:%M:%S %z" "${postYear}-${postMonth}-${postDay} ${postHourGmt}:${postMinute}:${postSecond} +0000" +%Y`
...where the variables were giving input into the date that I wanted to pull something out of...
...and the year (%Y) was what I was pulling out.

Bash script to iterate through a specific time range, one second at a time

I am trying to create some sort of loop in bash that will iterate through a specific time range, one second at a time.
At each interval, it will perform a duty with that timestamp I.e. "Wed Mar 2 12:00:03 CDT 2018"
I am having a hard time wrapping my head around how to make a loop that will iterate every second of time, and when it hits 60 seconds, update the minute, etc.
Thoughts? This seems obvious but the right syntax escapes me.
this is one way of doing it, delegate time computations to date
$ for i in {1..10}; do date -d "+$i seconds"; done
Sun Mar 11 20:40:57 UTC 2018
Sun Mar 11 20:40:58 UTC 2018
Sun Mar 11 20:40:59 UTC 2018
Sun Mar 11 20:41:00 UTC 2018
Sun Mar 11 20:41:01 UTC 2018
Sun Mar 11 20:41:02 UTC 2018
Sun Mar 11 20:41:03 UTC 2018
Sun Mar 11 20:41:04 UTC 2018
Sun Mar 11 20:41:05 UTC 2018
Sun Mar 11 20:41:06 UTC 2018
Sun Mar 11 20:41:07 UTC 2018
if you want to iterate up to a certain time, change the for loop to a while loop and a counter.
To make a loop with time you need to format date/time in such a way that can be comparable. The most easy trick is to transform date to something that will look like an integer and you then use lt,le,eq,gt,ge operators of bash.
Consider this :
$ date
Mon Mar 12 00:16:29 EET 2018 #this format/data type is not comparable by bash
$ date +%Y%m%d%H%M%S
20180312001629 #this is an integer representing the current time
This is a sample loop from now up to a specific time point:
stop=$(date +%Y%m%d%H%M%S --date "2018-03-12 00:20:55")
while [[ $(date +%Y%m%d%H%M%S) -le $stop ]];do #comparing current date & time with stop date & time
echo "date now is $(date)";
sleep 1; #sleep 1 second
done
date now is Mon Mar 12 00:20:51 EET 2018
date now is Mon Mar 12 00:20:52 EET 2018
date now is Mon Mar 12 00:20:53 EET 2018
date now is Mon Mar 12 00:20:54 EET 2018
date now is Mon Mar 12 00:20:55 EET 2018
The trick here is that the command
stop=$(date +%Y%m%d%H%M%S --date "2018-03-12 00:20:55")
converts given date (using the --date flag) to a kind of integer format.
Then the while loop keeps comparing current date in the same integer format with the stop date.
This is a similar script to start/stop at a specific time, but it is a bit "resources hungry" since it keeps comparing current time to start time:
date; #just print the current date & time
compl=false;
start=$(date +%Y%m%d%H%M%S --date "2018-03-12 01:45:50");
stop=$(date +%Y%m%d%H%M%S --date "2018-03-12 01:45:55");
while true;do
while [[ $(date +%Y%m%d%H%M%S) -ge $start ]] && [[ $(date +%Y%m%d%H%M%S) -le $stop ]];do
echo "date now is $(date)";
sleep 1;
compl=true;
done;
($compl) && break;
done
Mon Mar 12 01:45:37 EET 2018
date now is Mon Mar 12 01:45:50 EET 2018
date now is Mon Mar 12 01:45:51 EET 2018
date now is Mon Mar 12 01:45:52 EET 2018
date now is Mon Mar 12 01:45:53 EET 2018
date now is Mon Mar 12 01:45:54 EET 2018
date now is Mon Mar 12 01:45:55 EET 2018
An alternative to start/stop a script at specific time would be to use epoch date / epoch seconds.
Epoch date is measured in seconds since the epoch (1970-01-01 UTC).
Every date can be expressed as epoch seconds, using the format date +%s.
date #just print the current date & time
start="2018-03-12 02:17:52"
stop="2018-03-12 02:17:57"
timerequired=$(( $(date +%s --date "$start") - $(date +%s) ))
sleep $(($timerequired)) #sleep till the starting time
while [[ $(date +%s) -le $(date +%s --date "$stop") ]];do
echo "date now is $(date)";
sleep 1;
done
Mon Mar 12 02:17:39 EET 2018
date now is Mon Mar 12 02:17:52 EET 2018
date now is Mon Mar 12 02:17:53 EET 2018
date now is Mon Mar 12 02:17:54 EET 2018
date now is Mon Mar 12 02:17:55 EET 2018
date now is Mon Mar 12 02:17:56 EET 2018
date now is Mon Mar 12 02:17:57 EET 2018
Finally, you can use external tools to automate things based on date & time like cron, anacron , at, etc
Echo a date for every second in a range:
from=$(date -d "Wed Mar 2 12:59:58 CDT 2018" +%s)
to=$(date -d "Wed Mar 2 13:00:04 CDT 2018" +%s)
for s in $(seq $from $to); do echo $(date -d #$s); done
The date -d takes a well formed date as input. +%s formats it into seconds since epoch. So you get two big values like from=1520013598, to=...3604. The date -d #1520013598 transforms the timestamp back to a human readable date.
Your range might be in a variable like start and stop, and you might like to foobar ($time) instead of echoing it:
start="Wed Mar 2 12:59:58 CDT 2018"
stop="Wed Mar 2 13:00:04 CDT 2018"
from=$(date -d "$start" +%s)
to=$(date -d "$stop" +%s)
for s in $(seq $from $to)
do
timestamp=$(date -d #$s)
foobar $timestamp
done

How to find date n days in the future from past date?

I want to find a date that is 57 –working– days after an arbitrary date using date or bash. For instance,
today is august 21st,
reference date is july 15th,
what days will be 57 working days after july 15th?
This should work to just get all days
date -d '7/15/14 +57 days'
To get number of work days (M..F) you can do something lazy like this
#!/bin/bash
days=0
for ((i=1;i>0;i++)) do
future=$(date -d "7/15/14 +$i days" '+%w')
((future!=0 && future!=6)) && ((days++)) # ignore sunday (0) and saturday (6)
((days==57)) && date -d "7/15/14 +$i days" && break
done
e.g.
> ./abovescript
> Thu Oct 2 00:00:00 CDT 2014
Weird solution:
day=21
mon=8
year=2014
days=4
curl -s "http://www.timeanddate.com/scripts/dateserver.php?mode=addweekdays&d1=$day&m1=$mon&y1=$year&type=add&ad=$days&atyp=0&ach=3" | sed -n 's|.*<h2>Result: \(.*\)</h2>.*|\1|p'
prints
Wednesday, August 27, 2014
the date after 4 working days from 2014.08.21
for the
day=15
mon=7
year=2014
days=57
prints
Friday, October 3, 2014

How to compute a relative date from a given date?

The GNU date command can output date computed from relative items such as -1 hour or 1 month ago. It can also output date from different input format (for instance calendar date, seconds since epoch, etc...).
Is it possible to combine both a date format and a relative time to compute a new date from a given date using the GNU§ date utility?
Something like:
date_epoch=`date "+%s"`
date --date="#$date_epoch -1 month"
The second command gives an "incorrect date" error...
You can do it, sure:
$ date -d"$(date -d#$date_epoch) -1 month" "+%Y-%m-%d"
2013-09-16
Which comes from:
$ date_epoch=$(date "+%s")
$ date -d#$date_epoch
Wed Oct 16 23:46:50 CEST 2013
that you can use it "hardcoded":
$ date -d"Wed Oct 16 23:46:50 CEST 2013 -1 month"
Mon Sep 16 23:46:50 CEST 2013
Or using the variable:
$ date -d"$(date -d#$date_epoch) -1 month"
Mon Sep 16 23:46:50 CEST 2013

Resources