18

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

jasonwryan
  • 73,126
Ducky
  • 193

4 Answers4

24

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 08 and 09 (where the shell complains about it being an invalid octal number).

15

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

date -d "1970-01-01 UTC $(date +%T)" +%s
Ipor Sircer
  • 14,546
  • 1
  • 27
  • 39
  • 1
    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
  • 3
    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 06:45
  • 1
    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. –  Mar 10 '21 at 23:15
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
fedorqui
  • 7,861
  • 7
  • 36
  • 74
1

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') )) ;}
Pourko
  • 1,844