8

I need to increment minutes and seconds (in relation to time) in a variable.

First, I'm not sure whether declaring a 'time' variable is written as

time="00:00:00" 

or

 time=$(date +00:00:00)?

From there, I want to increment this variable by 10 minutes and seconds resulting in

01:00:00 increased to
01:10:10 to
01:20:20 etc (all the way up to midnight - 00:00:00)

What would be the best way to achieve this?

I understand that doing $ date -d "2010-07-07 200 days" adds (200) days but I don't know how to apply this example to time (minutes and seconds) and not date?

All replies are much appreciated.

cbros2008
  • 353
  • 1
  • 7
  • 23
  • You should clarify the objectives and constraints that you have, especially if this is a homework question (if so, it should be tagged as such). Running an external executable such as `date` many times in a loop can be very slow, but may greatly simplify the code. If you need to improve the performance, you'll need to code something more complex and do the incrementing, modulus and carry yourself. Bash doesn't have a concept of a "time variable". If you use `date` you need to use something it understands (your first example, perhaps). Otherwise you'll have to use Bash's strings and integers. – Dennis Williamson Oct 22 '10 at 00:44

2 Answers2

6

Note that this is Linux only. date -d on BSD unixes (and possibly others) does something significantly different (and untoward).

You could use epoch time - i.e., seconds since 1 Jan 1970 00:00:00, for example:

#!/bin/bash

time=0
echo `date -d "1970-01-01 00:00:00 UTC $time seconds" +"%H:%M:%S"`
time=$((time + 600))
echo `date -d "1970-01-01 00:00:00 UTC $time seconds" +"%H:%M:%S"`
time=$((time + 600))
echo `date -d "1970-01-01 00:00:00 UTC $time seconds" +"%H:%M:%S"`

gives this output:

$ /tmp/datetest.sh
00:00:00
00:10:00
00:20:00
$
Chris J
  • 30,688
  • 6
  • 69
  • 111
  • `+"%H:%M:%S"` is equivalent to `%T` afair – Andrey Regentov Mar 12 '14 at 09:48
  • Alas, the `-d` option to `date` does something completely different from what you intend in BSD unices and macOS. This solution is Linux-specific, even though the question was not. – ghoti Jan 17 '18 at 03:26
  • @ghoti - it's semi-implied by the question as he includes a -d example. However it's a fair point on the answer, I'll edit accordingly to make that clear. – Chris J Jan 17 '18 at 19:48
0

The date command is not part of bash. It's provided by your operating system, and its behaviour differs in different operating systems. Notably, GNU coreutils date (in most Linux distros) has a -d option used for interpreting source dates, whereas BSD date has a -f option for interpreting specifically formatted input dates and a -v option for adjusting times by various units.

You've already got an accepted answer for the Linux option. To be complete about this, here's a BSD (and macOS) option:

$ for (( s=0; s<86400; s+=610 )); do date -j -v+${s}S -f '%H:%M:%S' "$time" '+%T'; done | head -5
00:00:00
00:10:10
00:20:20
00:30:30
00:40:40

Output here is obviously trimmed to 5 lines.

Of course, this is still platform-specific. If you want something that will work with bash anywhere, then as long as you're using bash >4.2, the following might do:

$ offset=$(printf '%(%z)T\n' 0)
$ for (( s=$(( ${offset:1:2}*3600 + ${offset:3}*60 )); s<86400; s+=610 )); do printf '%(%T)T\n' "$s"; done | head -5
00:00:00
00:10:10
00:20:20
00:30:30
00:40:40

The $offset variable allows us to compensate for the fact that you may not be in UTC. :) Like the date solution, this steps through increments of 610 seconds, but it uses printf's %T format to generate output. You may with to add or subtract the timezone offset to the 86400 end point to get a full day of times. Handling that is left as an exercise for the reader. :-)

ghoti
  • 45,319
  • 8
  • 65
  • 104