The UNIX and Linux Forums  
Hello and Welcome from United States to the UNIX and Linux Forums! Thank You for Visiting and Joining Our Global Community.

Go Back   The UNIX and Linux Forums > Top Forums > UNIX for Dummies Questions & Answers
.
google unix.com




View Single Post in the UNIX and Linux Forums - Click on the Thread or Permalink to View Entire Thread -->
  #4 (permalink)  
Old 09-29-2006
boppr6470 boppr6470 is offline
Registered User
  
 

Join Date: Aug 2006
Posts: 8
And Now for Something Different

I've used this before and it works pretty well.
Does a few different things with dates depending on the parameters.

#! /usr/bin/ksh

# datecalc -- Perderabo's date calculator
#

USAGE="\
datecalc -a year month day - year month day
datecalc -a year month day [-|+] n
datecalc -d year month day
datecalc -D year month day
datecalc -j year month day
datecalc -j n
datecalc -l year month
use \"datecalc -help\" use for more documentation"

DOCUMENTATION="\
datecalc Version 1.1

datecalc does many manipulations with dates.
datecalc -a is for date arithmetic
datecalc -d or -D converts a date to the day of week
datecalc -j converts to date to or from julian day
datecalc -l outputs the last day of a month

All dates must be between the years 1860 and 3999.

datecalc -a followed by 7 parameters will calculate the
number of days between two dates. Parameters 2-4 and 6-8
must be dates in ymd form, and parameter 5 must be a minus
sign. The output is an integer. Example:

> datecalc -a 1960 12 31 - 1922 2 2
14212


datecalc -a followed by 5 parameters will calculate the
a new date offset from a given date, Parameters 2-4 must
be a date in ymd form, paramter 5 must be + or -, and
paramter 6 must be an integer. Output is a new date.
Example:

> datecalc -a 1960 12 31 + 7
1961 1 7


datecalc -d followed by 3 parameters will convert a date
to a day-of-week. Parameters 2-4 must be a date in ymd
form. Example:

> datecalc -d 1960 12 31
6


datecalc -D is like -d except it displays the name of
the day. Example:

> datecalc -D 1960 12 31
Saturday


datecalc -j followed by 3 parameters will convert a date
to Modified Julian Day number. Example:
> datecalc -j 1960 12 31
37299


datecalc -j followed by a single parameter will convert
a Modified Julian Day number to a date. Example:
> datecalc -j 37299
1960 12 31


datecalc -l followed by year and month will output the last
day of that month. Note that by checking the last day of
February you can test for leap year. Example:
> datecalc -l 2002 2
28"


lastday() {
integer year month leap
# ja fe ma ap ma jn jl ag se oc no de
set -A mlength xx 31 28 31 30 31 30 31 31 30 31 30 31

year=$1
if ((year<1860 || year> 3999)) ; then
print -u2 year out of range
return 1
fi
month=$2
if ((month<1 || month> 12)) ; then
print -u2 month out of range
return 1
fi

if ((month != 2)) ; then
print ${mlength[month]}
return 0
fi

leap=0
if ((!(year%100))); then
((!(year%400))) && leap=1
else
((!(year%4))) && leap=1
fi

feblength=28
((leap)) && feblength=29
print $feblength
return 0
}


date2jd() {
integer ijd day month year mnjd jd lday

year=$1
month=$2
day=$3
lday=$(lastday $year $month) || exit $?

if ((day<1 || day> lday)) ; then
print -u2 day out of range
return 1
fi

((standard_jd = day - 32075
+ 1461 * (year + 4800 - (14 - month)/12)/4
+ 367 * (month - 2 + (14 - month)/12*12)/12
- 3 * ((year + 4900 - (14 - month)/12)/100)/4))
((jd = standard_jd-2400001))


print $jd
return 0
}


jd2dow()
{
integer jd dow numeric_mode
set +A days Sunday Monday Tuesday Wednesday Thursday Friday Saturday

numeric_mode=0
if [[ $1 = -n ]] ; then
numeric_mode=1
shift
fi


jd=$1
if ((jd<1 || jd>782028)) ; then
print -u2 julian day out of range
return 1
fi

((dow=(jd+3)%7))

if ((numeric_mode)) ; then
print $dow
else
print ${days[dow]}
fi
return
}

jd2date()
{
integer standard_jd temp1 temp2 jd year month day

jd=$1
if ((jd<1 || jd>782028)) ; then
print julian day out of range
return 1
fi
((standard_jd=jd+2400001))
((temp1 = standard_jd + 68569))
((temp2 = 4*temp1/146097))
((temp1 = temp1 - (146097 * temp2 + 3) / 4))
((year = 4000 * (temp1 + 1) / 1461001))
((temp1 = temp1 - 1461 * year/4 + 31))
((month = 80 * temp1 / 2447))
((day = temp1 - 2447 * month / 80))
((temp1 = month / 11))
((month = month + 2 - 12 * temp1))
((year = 100 * (temp2 - 49) + year + temp1))
print $year $month $day
return 0
}


#
# Parse parameters and get to work.
case $1 in
-a) if (($# == 8)) ; then
if [[ $5 != - ]] ; then
print -u2 - "$USAGE"
exit 1
fi
jd1=$(date2jd $2 $3 $4) || exit $?
jd2=$(date2jd $6 $7 $8) || exit $?
((jd3=jd1-jd2))
print $jd3
exit 0
elif (($# == 6)) ; then
jd1=$(date2jd $2 $3 $4) || exit $?
case $5 in
-|+) eval '(('jd2=${jd1}${5}${6}'))'
jd2date $jd2
exit $?
;;
*)
print -u2 - "$USAGE"
exit 1
;;
esac

fi
;;

-d|-D) if (($# != 4)) ; then
print -u2 - "$USAGE"
exit 1
fi
jd1=$(date2jd $2 $3 $4) || exit $?
numeric=-n
[[ $1 = -D ]] && numeric=""
eval jd2dow $numeric $jd1
exit $?
;;

-j) if (($# == 4)) ; then
date2jd $2 $3 $4
exit $?
elif (($# == 2)) ; then
jd2date $2 $3 $4
exit $?
else
print -u2 - "$USAGE"
exit 1
fi
;;

-l) if (($# == 3)) ; then
lastday $2 $3
exit $?
else
print -u2 - "$USAGE"
exit 1
fi
;;

-help) print - "$USAGE"
print ""
print - "$DOCUMENTATION"
exit 0
;;

*) print -u2 - "$USAGE"
exit 0
;;


esac

#not reached
exit 7