17

How can you calculate the number of days since 1/1/1970? This is for updating the shadowLastChange attribute on OpenLDAP.

Is there a way to do this using the linux date command?

2
  • In Bash and most modern Bourne-derived shells, $() is preferred over backticks for readability and other reasons. echo $(( $(date ...) / 86400 )) Jan 10, 2011 at 14:03
  • Don't have 2000 yet... can someone edit and fix the title :-)
    – Déjà vu
    Jan 10, 2011 at 14:32

4 Answers 4

25

ring0 beat me by a few seconds, but the full command is:

echo $(($(date --utc --date "$1" +%s)/86400))

This goes by UTC time. Result:

root@hostname:~# echo $((`date --utc --date "$1" +%s`/86400))
14984

A quick check with WolframAlpha shows that this is the correct value.

2
  • 1
    what about leap seconds? :)
    – netvope
    Feb 21, 2015 at 23:43
  • 1
    @netvope After an additional leap second, unix time is reset by one again. So each day adds exactly 86400 unix seconds. However, unix time 915148800 may stand for both UTC 1998-12-31T23:59:60 and 1999-01-01T00:00:00 en.wikipedia.org/wiki/Unix_time#Leap_seconds
    – Debilski
    Feb 1, 2016 at 12:14
13

I think this is the simplest method:

expr $(date +%s) / 86400
1
  • 2
    Why is this downvoted? It's the best and shortest and simplest answer Sep 13, 2016 at 21:21
11

The date command can give you the number of seconds since 1970-01-01 00:00:00 UTC.

  date +"%s"

You can divide the result by 3600*24 to get the number of days (UTC).

E.g. in Bash

  x=`date +"%s"` ; echo $(( $x / 3600 / 24 ))

to display the number of days.

2

I needed to solve this as well, but I wanted to get the same value for the day# regardless of time of day. With approaches like those shown here, the value will change at midnight UTC instead of midnight local time. This probably seems like less of an issue in the EU or the U.S. East Coast, which are close enough to UTC that the day value won't change in the middle of the typical work day, but in, e.g., California, the day change would occur at 4pm PST, which might be inconvenient. I imagine Australians would be especially annoyed to have the day value change in late morning.

If we want to correct for that, we need to add the offset from UTC before dividing by secs/day. Fortunately, the Linux date command includes a %z format sequence which reports the offset from UTC. While the standard format (this result is for Denver time, MDT):

$ date +%z
-0600

. . . isn't directly usable in a calculation, the right modifiers will yield what we want:

$ date +%-:::z
-6

Put that together with the usual secs/hours/days conversions, and I believe the following should output the days since 1/1/1970, with 1/1/1970 itself being day zero, and the value incrementing at midnight local time:

echo $(( ( $(date +"%s + ( %-:::z * 3600)") ) / 86400 ))

This simple calculation will not work for time zones that are not offset from UTC by whole hours (e.g., India, TZ=Asia/Kolkata), since the "+5:30" produced by date +%-:::z will produce an "invalid character in expression" error when used in the above statement.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .