Link to home
Start Free TrialLog in
Avatar of calliope
calliope

asked on

Korn Shell Newbie Scripter: Date arithmetic

I am writing a korn shell script that takes in the date in the form of YYYY MM DD as parameters.  I need to do a check so that the date entered is no more than three days before the current date, or no later than the current date.  

The minimum information I need is how to calculate the date of three days before today, and then format it to '*%Y %m %d' and compare it to the input.

My ideal situation would be for someone out there to write a test that takes the input, makes sure it falls within the boundaries, and ensures that the input is formatted to YYYY MM DD.

Thanks!
Avatar of ozo
ozo
Flag of United States of America image

#!/bin/ksh
threedaysago=`perl -e '($y,$m,$d)=(localtime(time-3*24*60*60))[5,4,3];$y+=1900;$m+=1;printf"%04d %02d %02d",$y,$m,$d'`
today=`date +"%Y %m %d`
if [[ "$1" < "$threedaysago" || "$today" < "$1" ]] ;then
  echo bad date $1
else
  echo good date $1
fi
Avatar of calliope
calliope

ASKER

That works -- thanks ozo!

I'm just a little bit uncomfortable about introducing perl into the script, because if the script gets migrated somewhere where perl is not installed, it will break.  I'm increasing the value
A way that works wihout perl on some systems is to set your TZ offset 72 hour ahead,
but that's not portable to systems that don't allow large timezone offsets
Or, there's a big messy numerical computation you could do purely in ksh, which I can post if you're interested
this was a Bourne shell script from Q.10029753, but it works in ksh too:

dy=`date +%j`
yy=`date +%Y`
y1=`expr $yy - 1`
dd=`expr $dy + $y1 \* 365 + $y1 / 4 - $y1 / 100 + $y1 / 400`
d=`expr $dd - 3`
y1=`expr $d \* 400 / 146097`
y=`expr $y1 + 1`
d=`expr $d - $y1 \* 365 - $y1 / 4 + $y1 / 100 - $y1 / 400`
l=`expr \( $y % 4 \| $y % 100 = 0 \& $y % 400 \) = 0`
d=`expr $d + \( $d \> 59 + $l \) \* \( 2 - $l \)`
m=`expr \( $d + 183 \) \* 12 / 367`
d=`expr $d + 183 - $m \* 367 / 12`
m=`expr \( $m + 6 \) % 12 + 1`
echo $y $m $d
you may fiddle around with:

   env TZ=GMT+3 date
   env TZ=GMT-3 date

But , as ozo said, it may not work on all UNIX flaviours; most will reject to do it switching for or back over new year (which will be handled by ozo's script).
Short solution may be worth a try ..
ASKER CERTIFIED SOLUTION
Avatar of mliberi
mliberi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
> #   1900 < Y < 2100
1900 was not a leap year
in fact I wrote 1900 < Y (not 1900 <= Y)

Close enough.  Thanks!