OsmAnd/config/server_indexes_scripts/datecalc
2011-09-13 23:43:00 +00:00

268 lines
6.3 KiB
Bash
Executable file

#! /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