Operating System - HP-UX
1832806 Members
3067 Online
110045 Solutions
New Discussion

Re: Date arithmetic within shell

 
SOLVED
Go to solution
James A. Donovan
Honored Contributor

Date arithmetic within shell

Can anyone help me?

How do I perform arithmetic on dates within a shell script? I need to set a variable equal to something like "Now - 6 days", and, as if that wasn't enough, the final format of this date variable needs to be "MM/DD/YY HH:MM:SS". This is because the variable gets passed as a parameter to an executable which expects it in that format.

TIA,

Jim
Remember, wherever you go, there you are...
3 REPLIES 3
James R. Ferguson
Acclaimed Contributor
Solution

Re: Date arithmetic within shell

Hi Jim:

A C-program. Perl, awk or a shell function -- any of which you develop is needed for date offsets greater than 24-hours.

See this thread for an awk program (Al Langen's contribution) that does what you want:

http://forums.itrc.hp.com/cm/QuestionAnswer/1,1150,0x57eff841489fd4118fef0090279cd0f9,00.html

For a very clever computation of a dates +- 24-hours using the TZ variable, follow Rich Garland's contributions through the discussion referenced in this thread:

http://forums.itrc.hp.com/cm/QuestionAnswer/1,1150,0xf9fd5f260cafd4118fef0090279cd0f9,00.html

Regards!

...JRF...
James A. Donovan
Honored Contributor

Re: Date arithmetic within shell

Thanks James! I too found Al's code just after posting my plea for help.

I've tweaked it slightly so that it can handle subtracting any number of days from the date passed into it.

x=`date +%x`
z=6;export z
y=`echo $x|awk whatever.awk`

Returns a valid value for any value of z, where z does not result in a date from prior to the previous year. That is, if x="01/10/01", a z>=376 will return an invalid date.

BEGIN{ FS="/"
split( "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", month," ");
split( "31 28 31 30 31 30 31 31 30 31 30 31", days, " ");
}
{
year = $3
leapyear = year % 4;
if( leapyear == 0 )
days[2] = 29
else
days[2] = 28;
doy = 0;
for ( i = 1; i< $1; i++ )
doy = doy + days[i]
doy = doy + $2;
if ( doy <= ENVIRON["z"] )
{
doy = doy + 365;
year = year - 1;
leapyear = year %4;
if( leapyear == 0 )
{
days[2] = 29;
doy = doy + 1;
}
}
doy = doy - ENVIRON["z"];
for ( i = 1; i <= 12; i++ )
{
doy = doy - days[i];
if ( doy <= 0 )
{
doy = doy + days[i];
break;
}
}
printf( "%d/%d/%d", i, doy, year )
}
Remember, wherever you go, there you are...
David DeMartini_1
New Member

Re: Date arithmetic within shell

There is a REAL simple way to do this.

Here is a PERL example:

use Time::Local;
$yy = `date +%y`;
$mm = `date +%m`;
$day = `date +%d`;
chomp($day);
chomp($yy);
chomp($mm);
$start = timelocal("00", "00", "00", $day, ($mm-1), $yy);
$pcurr = $start - (7*86400); # get day 7 days prior
$fcurr = $start + (7*86400); # get day 7 days in future
print "\nDate: ".localtime($fcurr); # or pcurr for past

# you can also grab the elements and apply them to some hashes for conversions if you like.
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$dst)=localtime($fcurr); # or use pcurr if you want the past

Basically it is three steps.

1. Get the current date/time in seconds (easy on UNIX)
2. Add the number of days * 86400
3. Convert the seconds to human readable date/time.

Have fun!
Laziness is the father of invention.