13

Using the date program, how can I calculate the number of seconds since midnight?

2
  • 1
    date "+(%H*60+%M)*60+%S" | bc – groxxda Jul 25 '14 at 13:42
  • 2
    echo $(($(date '+(%H*60+%M)*60+%S'))) – groxxda Jul 25 '14 at 13:59
19

To avoid race conditions, still assuming GNU date:

eval "$(date +'today=%F now=%s')"
midnight=$(date -d "$today 0" +%s)
echo "$((now - midnight))"

With zsh, you can do it internally:

zmodload zsh/datetime
now=$EPOCHSECONDS
strftime -s today %F $now
strftime -rs midnight %F $today
echo $((now - midnight))

Portably, in timezones where there's no daylight saving switch, you could do:

eval "$(date +'h=%H m=%M s=%S')"
echo "$((${h#0} * 3600 + ${m#0} * 60 + ${s#0}))"

The ${X#0} is to strip one leading 0 which in some shells like bash, dash and posh cause problems with 09 (where the shell complains about it being an invalid octal number).

2
  • Very clever and good use of eval – Ulrich Dangel Jul 25 '14 at 13:14
  • I'd rather use something along these lines: IFS=: read -r today now <<< $(date +%F:%s); midnight=$(date -d "$today 0" +%s); echo $(( now - midnight )) – x-yuri May 3 '18 at 20:41
10

There is no need for any arithmetic expression, just use pure date:

date -d "1970-01-01 UTC $(date +%T)" +%s
4
  • Great answer, should be the top one. – Leopoldo Sanczyk Mar 28 '19 at 19:02
  • 1
    On Mac brew install coreutils and replace date with gdate – Connor McCormick Aug 12 '19 at 20:48
  • 2
    In timezones with daylight saving time, that gives incorrect results 2 days per year. For instance, in the UK at 2am on 2020-10-25 (the last Sunday in October), which is 3 hours after midnight as there have been a time change at 1am earlier, it gives 7200 instead of 10800. – Stéphane Chazelas Jun 28 '20 at 6:45
  • Actually, arithmetic expressions can be much faster than shelling out to external command twice. There are other ways to do the job, with calling date only once. – Chota Mar 10 at 23:15
3

Seconds since midnight?

For Bash (with GNU date) here are two one-liners which work equally well:

echo $(( - $(date -d 0 +%s) + EPOCHSECONDS ))

or

echo $(( $(date '+%-H *3600 + %-M *60 + %-S') ))

Either one works just as well.

Similarly, I find it useful to have a function for minutes since midnight:

minutes () { echo $(( $(date '+%-H *60 + %-M') )) ;}
2

Based on bash, get current time in milliseconds since midnight, on a GNU system, it can be done like this:

$ now=$(date '+%s')
$ midnight=$(date -d 'today 00:00:00' '+%s')
$ echo $(( now - midnight ))
53983
2
  • 2
    You want to make sure you don't do that at 23:59:59 – Stéphane Chazelas Jul 25 '14 at 13:02
  • And to convert back: date -d @$seconds – choroba Jul 25 '14 at 13:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.