The following function library might be of some help to you. I got the outline logic for this from somewhere in the internet and added my improvements to these functions.
#=========================================================================
dateAdd() # Adds number of days to a given date
#=========================================================================
# ARG_1 -> The date to add days DDMMYYYY format
# ARG_2 -> The number of days to add
# ARG_3 -> The date is returned in which format?
# 1 -> dd/mm/yyyy
# 2 -> mm/dd/yyyy
# 3 -> dd/mm/yy
# 4 -> mm/dd/yy
{
# Check that the input is valid.
# There should be exactly 3 arguments
if [ $# -ne 3 ]; then
return 1
fi
# The argument should be an integer.
n=`expr $2 + 0 2> /dev/null`
if [ $? -ne 0 ]; then
qnbad=0
elif [ $n -lt 0 ]; then
qnbad=0
else
qnbad=1
fi
if [ $qnbad -eq 0 ]; then
return 1
fi
# The "local" defnitions help to trickily
# return the values to the caller
local day=''
local month=''
local year=''
# Set the month day and year.
day=`echo $1 | cut -c1-2`
month=`echo $1 | cut -c3-4`
year=`echo $1 | cut -c5-8`
# Add 0 to month. This is a
# trick to make month an unpadded integer.
month=`expr $month + 0`
# Add n to the current day.
day=`expr $day + $n`
# Add months and subtract days until
# the future date is reached.
while : # Indefinite TRUE loop
do
# Determine the number of days in the
# current month.
case $month in
1|3|5|7|8|10|12) curMonthDay=31;;
4|6|9|11) curMonthDay=30;;
2)
if [ `expr $year % 4` -eq 0 ]; then
if [ `expr $year % 400` -eq 0 ]; then
curMonthDay=29
elif [ `expr $year % 100` -eq 0 ]; then
curMonthDay=28
else
curMonthDay=29
fi
else
curMonthDay=28
fi
;;
esac
# If the day is greater than the number
# of days in the current month then
# month is incremented; otherwise we are done.
if [ $day -gt $curMonthDay ]; then
day=`expr $day - $curMonthDay`
month=`expr $month + 1`
# If the month is 13 then it is jan of
# next year.
if [ $month -eq 13 ]; then
month=1
year=`expr $year + 1`
fi
else
break
fi
done
# Pad the integers before sending
[ $day -lt 10 ] && day="0$day"
[ $month -lt 10 ] && month="0$month"
# Print the month day and year according to the format
case "$3" in
1) echo $day'/'$month'/'$year;;
2) echo $month'/'$day'/'$year;;
3) echo $day'/'$month'/'`echo $year | cut -c3-4`;;
4) echo $month'/'$day'/'`echo $year | cut -c3-4`;;
esac
exit 0
}
#=========================================================================
dateSub() # Subtracts number of days to a given date
#=========================================================================
# ARG_1 -> The date to subtract days DDMMYYYY format
# ARG_2 -> The number of days to subtract
# ARG_3 -> The date is returned in which format?
# 1 -> dd/mm/yyyy
# 2 -> mm/dd/yyyy
# 3 -> dd/mm/yy
# 4 -> mm/dd/yy
{
# Check that the input is valid.
# There should be exactly 3 arguments.
if [ $# -ne 3 ]; then
return 1
fi
# The argument should be an integer.
n=`expr $2 + 0 2> /dev/null`
if [ $? -ne 0 ]; then
qnbad=0
elif [ $n -lt 0 ]; then
qnbad=0
else
qnbad=1
fi
if [ $qnbad -eq 0 ]; then
return 1
fi
# The "local" defnitions help to trickily
# return the values to the caller
local day=''
local month=''
local year=''
# Set the month day and year.
day=`echo $1 | cut -c1-2`
month=`echo $1 | cut -c3-4`
year=`echo $1 | cut -c5-8`
# Add 0 to month. This is a
# trick to make month an unpadded integer.
month=`expr $month + 0`
# Subtrace n from the current day.
day=`expr $day - $n`
# While the day is less than or equal to
# 0, deincrement the month.
while [ $day -le 0 ]
do
month=`expr $month - 1`
# If month is 0 then it is Dec of last year.
if [ $month -eq 0 ]; then
year=`expr $year - 1`
month=12
fi
# Add the number of days appropriate to the
# month.
case $month in
1|3|5|7|8|10|12) day=`expr $day + 31`;;
4|6|9|11) day=`expr $day + 30`;;
2)
if [ `expr $year % 4` -eq 0 ]; then
if [ `expr $year % 400` -eq 0 ]; then
day=`expr $day + 29`
elif [ `expr $year % 100` -eq 0 ]; then
day=`expr $day + 28`
else
day=`expr $day + 29`
fi
else
day=`expr $day + 28`
fi
;;
esac
done
# Pad the integers before sending
[ $day -lt 10 ] && day="0$day"
[ $month -lt 10 ] && month="0$month"
# Print the month day and year according to the format
case "$3" in
1) echo $day'/'$month'/'$year;;
2) echo $month'/'$day'/'$year;;
3) echo $day'/'$month'/'`echo $year | cut -c3-4`;;
4) echo $month'/'$day'/'`echo $year | cut -c3-4`;;
esac
exit 0
A Perderabo's script take on a other forum
It is really good
#! /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
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.