Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

On the Unix Bash commandline, I want to calculate the date from 1125 days ago using the base operating system (e.g. No Perl or Python).

On systems running GNU Date, I can do something like this:

ubuntu $ date --date="1125 days ago"
Wed Nov  7 15:12:33 PST 2007

FreeBSD or MacOSX systems don't ship with GNU Date, and don't support values like "X days ago".

freebsd81 $ date --date="+1125 days ago"
date: illegal option -- -

I can calculate a date from a few days ago on a Mac or FreeBSD system, but this is limited to a few days:

# Today is really Dec 6, 2010. 4 days ago it was:
macosx $ TZ=GMT+96 date +%Y%m%d
20101202

# But that doesn't work if I want to see the date 8 days ago:
macosx $ TZ=GMT+192 date +%Y%m%d
20101206

Can I calculate old dates on non-GNU systems without delving into tools like Perl or Python? Or must I use a more powerful scripting language?

share|improve this question

1 Answer 1

up vote 6 down vote accepted

Well, you can do something sneaky like:

$ echo "`date +%s` - (1125 * 24 * 60 *60)" |bc
1194478815
$ date -r 1194478689
Wed, 07 Nov 2007 18:38:09 -0500

Tested on OpenBSD (definitely non gnu based date), and seems to work.

Breaking it down in steps:

  • get the current unixtime (seconds since beginning of unix epoch):
  $ date +%s
  1291679934
  
  • get the number of seconds in 1125 days
  $ echo "1125 * 24 * 60 *60" | bc
  97200000
  
  • subtract one from the other (1291679934 - 97200000) = 1194478815

  • use the new unixtime (1194478815) to print a pretty date

    $ date -r 1194478689
    Wed, 07 Nov 2007 18:38:09 -0500
    
  • As an alternative, on solaris you can do this to print the date*:

    /bin/echo "0t1194478815>Y\n<Y=Y" |adb

* referenced from http://www.sun.com/bigadmin/shellme/

Also, an alternative on Solaris for getting the current timestamp from the date command** is:

/usr/bin/truss /usr/bin/date 2>&1 |  nawk -F= '/^time()/ {gsub(/ /,"",$2);print $2}'

** referenced from http://www.commandlinefu.com/commands/view/7647/unix-timestamp-solaris

share|improve this answer
    
Note that %s and date -r are BSDisms (from the very early days, so they're on all BSD platforms). Don't expect to see them on System V platforms (e.g. Solaris has neither). –  Gilles Dec 7 '10 at 0:09
    
Ah, Solaris, how I love thee... (; –  gabe. Dec 7 '10 at 0:14
    
@Gilles: Are you sure? Solaris has a multitude of bin directories, such as /usr/ucb/bin, that contain versions from other variations of unix. SunOS 4.X was BSD-based after all. –  camh Dec 7 '10 at 1:24
    
This fails when any of the intervening days have more or less than 60*60*24 seconds, such as leap seconds and calendar changes. –  Sparr Dec 7 '10 at 7:01
1  
@Sparr: Good point. A safe approach is to subtract the current time of day from the current absolute date, and add 12*60*60. This returns a time-of-day between 10:59 and 13:01. Adding 24-hour periods to this and obtaining the corresponding date is safe. –  Gilles Dec 7 '10 at 19:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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