3

Operating System: Red Hat Enterprise Linux Server 7.2 (Maipo)

I want to round the time to the nearest 5 minutes, only up, not down, for example:

08:09:15 should be 08:10:00

08:11:26 should be 08:15:00

08:17:58 should be 08:20:00

I have been trying with:

(date -d @$(( (($(date +%s) + 150) / 300) * 300)) "+%H:%M:%S")

This will round the time but also down (08:11:18 will result in 08:10:00 and not 08:15:00)

Any idea how i can achieve this?

ceving
  • 21,900
  • 13
  • 104
  • 178
Kevin
  • 143
  • 1
  • 8
  • 2
    Change 150 to 299. What you add to the time is the threshold for rounding up. If you add 150, it rounds up if you're within 150 seconds of the 5-minute line. If you add 299, it rounds up if you're within 299 seconds, which is always except when you're right on the previous line. Try it yourself on a piece of paper and convince yourself it works. – rici Aug 30 '18 at 07:31
  • Adding `299` will round `'08:15:00'` to `'08:15:00'` but IMO it should become `'08:20:00'` – anubhava Aug 30 '18 at 07:34
  • 1
    @jww i saw that post also, this will round up but in either way. I need to round up always to the above value, not below. – Kevin Aug 30 '18 at 08:55
  • 1
    This questions sounds like a duplicate, but it is not. It is titled with "rounding", but the question asks for "ceiling". I have flagged to reopen. – ceving Aug 30 '18 at 09:35
  • Linked question is not really a dup as OP always wants to round up. – anubhava Aug 30 '18 at 09:58

2 Answers2

2

You may use this utility function for your rounding up:

roundDt() {
   local n=300
   local str="$1"
   date -d @$(( ($(date -d "$str" '+%s') + $n)/$n * $n)) '+%H:%M:%S'
}

Then invoke this function as:

roundDt '08:09:15'
08:10:00    

roundDt '08:11:26'
08:15:00

roundDt '08:17:58'
08:20:00

To trace how this function is computing use -x (trace mode) after exporting:

export -f roundDt

bash -cx "roundDt '08:11:26'"

+ roundDt 08:11:26
+ typeset n=300
+ typeset str=08:11:26
++ date -d 08:11:26 +%s
+ date -d @1535631300 +%H:%M:%S
08:15:00
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Hi anubhava, if i want to use this function with the systime and store it in a variable, how can i achieve this? – Kevin Aug 30 '18 at 08:31
  • To call it for systime and save in a variable use: `newdt=$(roundDt "$(date '+%H:%M:%S')")` and then do `echo $newdt"` – anubhava Aug 30 '18 at 10:01
2

GNU date can calculate already. It is explained in the manual in the chapter "Relative items in date strings". So you need just one date call.

d=$(date +%T)                             # get the current time
IFS=: read h m s <<< "$d"                 # parse it in hours, minutes and seconds
inc=$(( 300 - (m * 60 + s) % 300 ))       # calculate the seconds to increment
date -d "$d $inc sec" +%T                 # output the new time with the offset

Btw: +%T is the same as +%H:%M:%S.

ceving
  • 21,900
  • 13
  • 104
  • 178