Roger Moore
Roger Moore

Reputation: 1121

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

Upvotes: 13

Views: 46829

Answers (6)

try this

date +%H%M%S -d "- 10 min"

is ok for me

Upvotes: 0

ChewySalmon
ChewySalmon

Reputation: 614

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'

Upvotes: 0

kSiR
kSiR

Reputation: 764

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

Upvotes: 5

griswolf
griswolf

Reputation: 69

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.

Upvotes: 1

Roger Pate
Roger Pate

Reputation:

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.

Upvotes: 1

wds
wds

Reputation: 32283

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"

Upvotes: 27

Related Questions