Round current time up and down - bash

I'm trying to figure out how to get the current hour rounded down to start of the hour and the next hour in bash?
For example, if I run my script:
./printHour.sh
and let's say the current time at execution is 13:04:12 - it would print
current hour is: 13:00:00
next hour is: 14:00:00
Progress so far: (but this gives 1hour ago so it does not work) - any ideas?
lastHour=$(date -d '1 hour ago' "+%H:%M:%S")
echo "current hour is: "$lastHour

You can use this utility function:
hrdt() { date -d "${1?} hour ago" '+%H:00:00'; }
Testing:
> hrdt
bash: 1: parameter not set
> hrdt 0
08:00:00
> hrdt 1
07:00:00
> hrdt 2
06:00:00
> hrdt 3
05:00:00

Could you please try following, written and tested as per shown samples, my date is GNU date version.
cat script.bash
#!/bin/bash
currentHour=$(date "+%H:00:00")
nextHour=$(date -d '+1 hour' "+%H:00:00")
echo "current hour is: $currentHour"
echo "next hour is: $nextHour"
When I run above script I get as follows:
current hour is: 06:00:00
next hour is: 07:00:00

Seems like you don't need anything special so this should do it:
date -d '1 hour ago' "+%H:00:00"
Why bother when you want exactly the hour where both %M and %S are expected to be zero?

You don't need date in this case; as seen below, built-in printf can generate formatted date-time strings too. Here -1 represents current time, and EPOCHSECONDS is a dynamic variable that expands to the number of seconds since epoch.
$ printf 'current hour is: %(%H)T:00:00\n' -1
current hour is: 17:00:00
$
$ printf 'next hour is: %(%H)T:00:00\n' $((EPOCHSECONDS + 3600))
next hour is: 18:00:00

Using awk,
$ awk ' BEGIN { st=systime();
print "current hour=" strftime("%F %H:00:00",st);
print "next hour=" strftime("%F %H:00:00",st+(60*60)) } '
current hour=2020-12-26 23:00:00
next hour=2020-12-27 00:00:00
$

Related

The date command appears to convert timezones the wrong way?

I'm working on a script where I need to convert the current time, in UTC to something else:
fmt="%Y-%m-%d %H:%M:%S"
tzone=America/Detroit
nowinutc=$(TZ=UTC date +"$fmt");echo $nowinutc
nowintz=$(date -d "TZ=\"$tzone\" $nowinutc" +"$fmt");echo $nowintz
yestintz=$(date -d "$nowintz - 1 day" +"$fmt");echo $yestintz
I know America/Detroit is 5 hours behind UTC, so 08:00:00 should become 03:00:00, but:
$ fmt="%Y-%m-%d %H:%M:%S"
$ tzone=America/Detroit
$ nowinutc=$(TZ=UTC date +"$fmt");echo $nowinutc
2022-02-11 08:49:51
$ nowintz=$(date -d "TZ=\"$tzone\" $nowinutc" +"$fmt");echo $nowintz
2022-02-11 13:49:51
$ yestintz=$(date -d "$nowintz - 1 day" +"$fmt");echo $yestintz
2022-02-12 14:49:51
It's probably not the date command that gets it wrong, but what am I doing wrong here? It looks like everything works the opposite way of expected. Not only does the timezone conversion add 5 hours, but subtracting 1 day adds 25 hours - what is going on here?
so 08:00:00 should become 03:00:00
Then the input is in UTC and you are in Detroit.
TZ=America/Detroit date -d "08:00:00 UTC" +%H:%M:%S
TZ=America/Detroit date -d "TZ=\"UTC\" 08:00:00" +%H:%M:%S
TZ=America/Detroit date -d "08:00:00+00:00" +%H:%M:%S
From man date examples:
Show the time on the west coast of the US (use tzselect(1) to find TZ)
$ TZ='America/Los_Angeles' date
Show the local time for 9AM next Friday on the west coast of the US
$ date --date='TZ="America/Los_Angeles" 09:00 next Fri'

Shell add day to date saved in parameter

Hoping someone can help me work out what on earth is happening here.
I've got a script which receives a date as a parameter in this format "2016-09-01 00:00:00" and should create another variable containing the date for one day in the future, code is below
currentDate=$1
currentDate=$(date +"%Y-%m-%d %H:%M:%S" -d "$currentDate")
nextDate=$(date +"%Y-%m-%d %H:%M:%S" -d "$currentDate + 1 day")
echo $currentDate
echo $nextDate
Sometimes this works perfectly fine for example
2016-09-01 00:00:00 - date given as parameter
2016-09-02 00:00:00 - output for next day
But sometimes it'll only add 23 hours depending on the date provided
2016-02-01 00:00:00 - date given as parameter
2016-02-01 23:00:00 - output for next day
if I change the nextDay variable to add three days as below
nextDate=$(date +"%Y-%m-%d %H:%M:%S" -d "$currentDate + 3 day")
it gives the output as below adding only 21 hours instead of 3 days
2016-02-01 00:00:00 - date given as parameter
2016-02-01 21:00:00 - output for next day
Could someone help me understand why this is happening, is it related to timezones?
The reason appears to be how difficult it is to do free-form date parsing:
A baseline date: (I'm in the America/Toronto time zone)
$ date -d "2016-11-06 01:00:00" "+%F %T%z"
2016-11-06 01:00:00-0400
Try adding a day
$ date -d "2016-11-06 01:00:00 + 1 day" "+%F %T%z"
2016-11-06 19:00:00-0500
Hmm, that's strange, looks like it's adding a day but then expressing it as midnight, then subtracting 5 hours.
Let's try adding a day to just the date part
$ date -d "2016-11-06 + 1 day 01:00:00" "+%F %T%z"
2016-11-07 01:00:00-0500
That looks better.
In your script try this:
read current_date current_time < <(date -d "$1" +"%F %T%z")
echo "$current_date $current_time"
next_day=$(date -d "$current_date + 1 day $current_time" +"%F %T%z")
echo "$next_day"
three_days=$(date -d "$current_date + 3 day $current_time" +"%F %T%z")
echo "$three_days"

Reading date with hour and incrementing it in shell script

I have a file with date '2015-06-01-12', how can I get it to increment the hour in shell script? The result I want is '2015-06-01-13'. If its the 23rd hour it has to move forward a date and get 00 as hour.
I was able to do it to date but have so far had not any luck with incrementing hours.
currDate=2015-06-02
nextDate=`date '+%Y-%m-%d' -d "$currDate+1 days"`
echo $nextDate
It is reasonably easy if you keep your date as an epoch (number of seconds since January 1, 1970):
$ currDate=$( date +%s -d "2015-06-02 23:00:00" )
$ echo $currDate
1433300400
$ date +%Y-%m-%d-%H -d #$currDate
2015-06-02-23
$ nextDate=$(( $currDate + 3600 )) #adding an hour's worth of seconds
$ date +%Y-%m-%d-%H -d #$nextDate
2015-06-03-00

date calculations in bash

I have a simple question.
date '+%Y%m%d' --date='20130417 2 day ago'
20130415
works fine.
I have an env var
today="20130417"
but the following command does not work.
date '+%Y%m%d' --date='$today 2 day ago'
any workarounds?
You need double quotes instead of single:
$ date '+%Y%m%d' --date="$today 2 day ago"
20130415
Otherwise, the values within --date=' ' don't get evaluated.
This is a general behaviour, see an example:
$ echo 'the date is: $today'
the date is: $today
$ echo "the date is: $today"
the date is: 20130417

Bash: subtracting 10 mins from a given time

In a bash script, if I have a number that represents a time, in the form hhmmss (or hmmss), what is the best way of subtracting 10 minutes?
ie, 90000 -> 85000
This is a bit tricky. Date can do general manipulations, i.e. you can do:
date --date '-10 min'
Specifying hour-min-seconds (using UTC because otherwise it seems to assume PM):
date --date '11:45:30 UTC -10 min'
To split your date string, the only way I can think of is substring expansion:
a=114530
date --date "${a:0:2}:${a:2:2}:${a:4:2} UTC -10 min"
And if you want to just get back hhmmss:
date +%H%M%S --date "${a:0:2}:${a:2:2}:${a:4:2} UTC -10 min"
why not just use epoch time and then take 600 off of it?
$ echo "`date +%s` - 600"| bc; date
1284050588
Thu Sep 9 11:53:08 CDT 2010
$ date -d '1970-01-01 UTC 1284050588 seconds' +"%Y-%m-%d %T %z"
2010-09-09 11:43:08 -0500
Since you have a 5 or 6 digit number, you have to pad it before doing string manipulation:
$ t=90100
$ while [ ${#t} -lt 6 ]; do t=0$t; done
$ echo $t
090100
$ date +%H%M%S --utc -d"today ${t:0:2}:${t:2:2}:${t:4:2} UTC - 10 minutes"
085100
Note both --utc and UTC are required to make sure the system's timezone doesn't affect the results.
For math within bash (i.e. $(( and ((), leading zeros will cause the number to be interpreted as octal. However, your data is more string-like (with a special format) than number-like, anyway. I've used a while loop above because it sounds like you're treating it as a number and thus might get 100 for 12:01 am.
My version of bash doesn't support -d or --date as used above. However, assuming a correctly 0-padded input, this does work
$ input_time=130503 # meaning "1:05:03 PM"
# next line calculates epoch seconds for today's date at stated time
$ epoch_seconds=$(date -jf '%H%M%S' $input_time '+%s')
# the 600 matches the OP's "subtract 10 minutes" spec. Note: Still relative to "today"
$ calculated_seconds=$(( epoch_seconds - 600 )) # bc would work here but $((...)) is builtin
# +%H%M%S formats the result same as input, but you can do what you like here
$ echo $(date -r $calculated_seconds '+%H%M%S')
# output is 125503: Note that the hour rolled back as expected.
For MacOS users you can do the following:
$(date -v -10M +"%H:%M:%S")
Date time without a specific format:
$(date -v -10M)
For non-macOS users:
Date time without a specific format:
date --date '-10 min'

Resources