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.

Is there any tool in Solaris UNIX (so no GNU tool available) to subtract dates? I know that in Linux we have gawk that can subtract one date from another. But in Solaris the maximum we have is nawk (improved awk) which cannot perform date calculations. Also I cannot use perl... :(

Is there anyway to do dates calculations like 20100909-20001010 ?

UPDATE: Is bc able to perform dates calculations?

Thanks guys

share|improve this question
1  
See also Quickly calculate date differences, for when GNU date is available. –  Gilles Nov 15 '11 at 23:27

9 Answers 9

up vote 6 down vote accepted

Here is an awk script I just wrote up, should work with an POSIX awk. You'll have to try the Solaris version; remember that there are two versions of Awk on Solaris as well, one in /bin and one in /usr/xpg4/bin/awk (which is nawk, I believe).

BEGIN {
    daysofmonth["01"] = 0; daysofmonth["02"] = 31; daysofmonth["03"] = 59;
    daysofmonth["04"] = 90; daysofmonth["05"] = 120; daysofmonth["06"] = 151;
    daysofmonth["07"] = 181; daysofmonth["08"] = 212; daysofmonth["09"] = 243;
    daysofmonth["10"] = 273; daysofmonth["11"] = 304; daysofmonth["12"] = 334;
    fullday = 86400;
}
/[12][09][0-9][0-9][01][0-9][0123][0-9]/ {
    year = substr($0, 1, 4); month = substr($0, 5, 2); day = substr($0, 7, 2);
    date = ((year - 1970) * 365.25) + daysofmonth[month] + day - 1;
    if ((year % 4) == 0 && month > 2) { date = date + 1; }
    print date * fullday - (25200);
}
{}

Pass a YYYYmmdd date string through and it will be converted to number of seconds since the Epoch (with a bit of give for being on day boundaries). Then you will be able to subtract the two.

today=`echo 20110210 | awk -f convdate.awk`
then=`echo 20001231 | awk -f convdate.awk`
sincethen=`expr $today - $then`
share|improve this answer
    
I checked your logic with Oracle. For some dates is ok, however for it generates a float number. I'm afraid I have to truncate to an integer number, is it? –  jyzuz Feb 17 '11 at 15:42
    
The decimal is the fraction of a second and not necessarily needed. –  Arcege Feb 17 '11 at 16:22

Perl is likely to be installed, and it's easy enough to grab modules from CPAN, install them in your home directory, and refer to them in your program. In this case, the Date::Calc module has a Delta_Days subroutine that will help.

share|improve this answer

Wrt GNU date on Solaris:

I say this again:

Too many Solaris SysAdmins take pride in deliberately not installing the official packages from Sun (now Oracle) that make a Solaris system "GNU compatible" when they configure a new host. Beats me why.

GNU Date is excellent and should be available by default on any Solaris host, IMHO.

On Solaris 10

Install package SFWcoreu from the Solaris Companion CD. After install you will find GNU date in /opt/sfw/bin/date

On Solaris 11

You may already have it as I believe it is part of the standard install. It is however called gdate in order to distinguish it from the Sun version of date.

Do this if not installed:

pkg install //solaris/file/gnu-coreutils
share|improve this answer
    
Thanks for the tip. Can you give me an example of how to use it? So I can ask sysadmin to install it... –  jyzuz Feb 27 '13 at 14:23
    
On Solaris 11, it will be installed as both /usr/bin/gdate and /usr/gnu/bin/date so you can choose to use it either by name or by $PATH setting. –  alanc Jul 6 '13 at 16:19

For the record, dateutils is my attempt at providing a set of portable tools that cover date arithmetics. Your example boils down to

ddiff -i '%Y%m%d' 20001010 20100909
=>
  3621

The -i specifies the input format.

share|improve this answer
    
This package is awesome, and it exists in the Ubuntu universe libraries (at least for Trusty). On another system, I could compile it easily from scratch. Highly recommended. Thank you very much! –  Robert Muil Oct 1 at 16:20

Unfortunately, none of the POSIX command line utilities provide arithmetic on dates. date -d and date +%s are the way to go if you have them, but they're GNU extensions.

There's a clumsy hack with touch that sort of works for checking that a date is at least n days in the past:

touch -t 201009090000 stamp
if [ -n "$(find stamp -mtime +42)" ]; then ...

(Note that this code may be off by one if DST started or stopped in the interval and the script runs before 1am.)

Several people have ended up implementing date manipulation libraries in Bourne or POSIX shell. There are a few examples and links in the comp.unix.shell FAQ.

Installing GNU tools may be the way of least pain.

share|improve this answer
    
Hey, you typoed the end of the FAQ url. –  intuited Sep 10 '10 at 0:25

python:

 from datetime import datetime as dt
 a = dt(2010, 9, 9)
 b = dt(2000, 10, 10)
 print (a - b).days
share|improve this answer

If you have Python:

from time import *
date1 = strptime("20100909","%Y%m%d")
date2 = strptime("20001010","%Y%m%d")
diff = mktime(date1) - mktime(date2)
print repr(d/86400) + " days"

You tagged your question "gawk" but you say "no GNU tools". Gawk has date arithmetic.

share|improve this answer
    
I didn't. Someone edited my post and tagged "gawk"... –  jyzuz Sep 9 '10 at 22:37

Install some tools!

I mean, it is Solaris, what do you expect? ;)

share|improve this answer
    
I don't have root access, neither compiler and libraries... In fact it's a server, and I have only user access. I think I'll have to build a function in awk... –  jyzuz Sep 9 '10 at 20:57

I would try using the date command which is part of POSIX so it is just about everywhere. UPDATE: Unfortunately, it seems that -d is not part of POSIX date and likely not there on Solaris. Thus this likely won't answer the OPs question.

d1=`date -d 20100909 +%s`
d2=`date -d 20001010 +%s`

Now d1 and d2 are integers that correspond to seconds since the unix epoch. Thus to get the difference between the two, we subtract( $((d1-d2)) in bash) and covert to whatever units we want. Days are the easiest:

echo "$(((d1-d2)/86400)) days"

How to do the conversion will likely be different if you don't have bash. The most portable way may be to use expr (expr's posix man page).

share|improve this answer
    
yeah this does not answer my question because it's Solaris... but thank you for the ideia and posting :) –  jyzuz Sep 9 '10 at 20:20

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.