阴阳历相互转换SHELL SCRIPT
时间:2005-03-04 来源:rollingpig
最近写了一个阴阳历相互转换SHELL SCRIPT.
大家有空试试。
#!/bin/bash#...Scripts to translate solar date to lunar date or translate lunar date to solar date
#Author:[email protected],from ChinaUnix.net
#!/bin/bash
#...Scripts to translate solar date to lunar date or translate lunar date to solar date
#Author:[email protected],from ChinaUnix.net#General settings,do not change these settings.
#general days per month in lunar
LUNARDAYSINMONTH=29#general days per year in lunar
((LUNARDAYSINYEAR=LUNARDAYSINMONTH*12))#general days per year
DAYSINYEAR=365
#days for leap year
LEAPDAYSINYEAR=366#END of General settings
#####################################################
#FLAG setting section
#This section can be extend by adding year-flag to the LUNARFLAG.
#If extend, remember to update the variables
#BASENUMBER
#STARTOFLUNARYEAR
#ENDOFLUNARYEAR
#start year of the lunar tab
STARTOFLUNARYEAR=1900
ENDOFLUNARYEAR=2049
#the diff day number of 1900-01-01 and 1900-01-01(In lunar)
BASENUMBER=31#lunar flag setting
LUNARFLAG="001001011110187 001001010111006 010100101011107 001010100110156 011010010011006 011011001010107 101100101010147 001010110101006 010011010110107 001010101110127 001001010111006 010100101101167 010100100110106 011010010010106 111010010010157 010110101010006 011010110101007 010101101101027 010010101101107 101001001011177 001001001011106 010100100101106 010110100101157 001101010010106 001101101010006 110101011010148 000101011011006 010010101011107 001010010111127 001001001011106 001100101011066 011010100101006 011101010010107 001101110100157 001011010110107 000101011011006 110000110111037 010010010111006 111001000110177 011001001010106 011010100101006 111011000101067 010110101010107 001010110101006 110100101101148 000100101110106 010010010110106 011010010101127 010101001010106 010110101010177 001101100101006 010110101010107 101010011010157 001001101101006 010100101110107 101000101011137 001010010110106 010101001101086 011101001010107 001101010101006 010101110101067 010101011010107 001001011011006 010101010111047 010100101011107 001010010011005 011110010011037 011011001010107 001011011010177 001010110101006 010010110110107 001001101110157 001001010110106 010100100110106 011010100110147 011010010010106 011010101010187 010110101010006 010110101101007 110010101101067 010010101101107 001001001101106 010101001011147 010100100101106 0101100100111a7 001101010010106 001101101010006 010101111010067 010101011011007 010010101011107 001001010111157 001001001011106 001100100101106 001110100101036 011101010010107 001101011010187 001010101110006 010101011011007 010010110110157 010010010111006 011001001011006 011011001010147 011010100101006 011011010010107 001110101010127 001010110101006 010101011101178 000100101110106 010010010110106 011001010101157 010101001010106 010110100101006 010111010101047 010101101010107 001010101110197 001001011101006 010100101101107 101010001011167 001010010101106 010101001001106 001111001010147 001101010101006 010101101010107 001011011010127 001001011011006 010100110111067 010100100111006 011010010011006 011101010011057 011010101001107 001011010101006 001110110101037 010010110110107 001001011110177 001001010110106 010100100110106 111010000101167 011010010010106 011010101001006 011011101010057 010110101101007 001010110110107 001010101101127 001001001101106 010100101011177 010100100101106 010101010010106 110110010010157 001101101001006 010101101101007 "
#format of lunar flag
#If you want to change the format,please also change the function set in Lunar base function section
#"001001011110187 ..."
#1: daysOfLeapMonth flag,0 stand for 29 ,1 standy for 30 days inthe month
LEAPMONTHDAYSOFF=0
#2-13: daysOfMonth's flag , 0 standy for 29 ,1 standy for 30 days in the month
#15: monthOfLeapYear flag,0 stand for no leap month,else stand for the leap month(a,b,c for 10,11,12)
LEAPMONTHOFF=13
#16: number of 30day's month in the year(include leap month)
DAY30INYEAROFF=14
#Number of offset per year
NUMOFFSETPERYEAR=16#End Of FLAG setting section
##############################################################
##############################################################
#Lunar base function section,
#Please change these if the format of lunar-flag changed
##funtion lunarLeapMonth,_lunarLeapMonth
#return the leap month of a given year,0 for none
function lunarLeapMonth {
_lunarLeapMonth $(($1-STARTOFLUNARYEAR))
}
#the parameter year is the actural year minus STARTOFLUNARYEAR
function _lunarLeapMonth {
_yr=$1
((_flagoffset=_yr*NUMOFFSETPERYEAR+LEAPMONTHOFF))
#echo $_flagoffset
_tmp_flag=${LUNARFLAG:$_flagoffset:1}
case $_tmp_flag in
a)
echo 10;return
;;
b)
echo 11;return
;;
c)
echo 12;return
;;
*)
echo $_tmp_flag;return
;;
esac
}#funtion lunarDaysOfLeapMonth,_lunarDaysOfLeapMonth
#return the days of leap month of a given year,0 for none
function lunarDaysOfLeapMonth {
_lunarDaysOfLeapMonth $(($1-STARTOFLUNARYEAR))
}
#the parameter year is the actural year minus STARTOFLUNARYEAR
function _lunarDaysOfLeapMonth {
_yr=$1
if [ "`_lunarLeapMonth $_yr`" == "0" ] ; then
echo 0;return
fi
((_flagoffset=_yr*NUMOFFSETPERYEAR+LEAPMONTHDAYSOFF))
_tmp_flag=${LUNARFLAG:$_flagoffset:1}
if [ "$_tmp_flag" == "0" ] ; then
echo 29
else
echo 30
fi
}
#funtion lunarDaysOfMonth,_lunarDaysOfMonth
#return the days of month of a given year and month
function lunarDaysOfMonth {
_lunarDaysOfMonth $(($1-STARTOFLUNARYEAR)) $2
}
#the parameter year is the actural year minus STARTOFLUNARYEAR
function _lunarDaysOfMonth {
_yr=$1
_mn=$2
((_flagoffset=$1*NUMOFFSETPERYEAR+$2))
_tmp_flag=${LUNARFLAG:$_flagoffset:1}
echo $((LUNARDAYSINMONTH+$_tmp_flag))
}#funtion lunarDaysOfYear,_lunarDaysOfYear
#return the amount of days of given year
function lunarDaysOfYear {
_lunarDaysOfYear $(($1-STARTOFLUNARYEAR))
}
#the parameter year is the actural year minus STARTOFLUNARYEAR
function _lunarDaysOfYear {
((_flagoffset=$1*NUMOFFSETPERYEAR+DAY30INYEAROFF))
_tmp_flag=${LUNARFLAG:$_flagoffset:1}
#echo $_tmp_flag
if [ "`_lunarLeapMonth $1`" == "0" ] ; then
echo $((LUNARDAYSINYEAR+_tmp_flag))
else
echo $((LUNARDAYSINYEAR+_tmp_flag+LUNARDAYSINMONTH))
fi
}#funtion lunarDaysInYear,_lunarDaysInYear
#return the days since the begining of same year of given year,month,day
function lunarDaysInYear {
_lunarDaysInYear $(($1-STARTOFLUNARYEAR)) $2 $3
}
#the parameter year is the actural year minus STARTOFLUNARYEAR
function _lunarDaysInYear {
_yr=$1 _mn=$2 _dy=$3
_days=$((_dy-1))
_leap_mn=`_lunarLeapMonth $_yr`
if [ $_mn -gt $_leap_mn ] ;then
((_days=_days+`_lunarDaysOfLeapMonth $_yr`))
fi
((_mn=_mn-1))
while [ $_mn -gt 0 ] ; do
((_days=_days+`_lunarDaysOfMonth $_yr $_mn`))
((_mn=_mn-1))
done
echo $_days
}#END of Lunar base function section
################################################################base function of solar calendar.
function isLeap {
_yr=$1
if [ $(( _yr % 400 )) -eq 0 ] ; then
echo 1;return
elif [ $(( _yr % 100 )) -eq 0 ] ; then
echo 0;return
elif [ $(( _yr % 4 )) -eq 0 ] ; then
echo 1;return
fi
echo 0
}function daysOfMonth {
_mn=$2
case $2 in
4|6|9|11)
echo 30;return
;;
2)
if [ `isLeap $1` == "1" ] ; then
echo 29;return
else
echo 28; return
fi
;;
*)
echo 31;return
;;
esac
}function daysOfYear {
if [ "`isLeap $1`" == "0" ] ; then
echo $DAYSINYEAR
else
echo $LEAPDAYSINYEAR
fi
}function daysInYear {
_yr=$1 _mn=$2 _day=$3
_days=$((_day-1))
((_mn=_mn-1))
while [ $_mn -gt 0 ] ; do
((_days=_days+`daysOfMonth $_yr $_mn`))
((_mn=_mn-1))
done
echo $_days
}#date to number of days
function dayToNumber {
_yr=$1
_mn=$2
_dy=$3
_days=`daysInYear $_yr $_mn $_dy`
while [ $_yr -gt $STARTOFLUNARYEAR ] ; do
((_yr=_yr-1))
((_days=_days+`daysOfYear $_yr`))
# echo $_days $_yr
done
echo $_days
}
#lunar date to number of days
function lunarDayToNumber {
_lunarDayToNumber $(($1-STARTOFLUNARYEAR)) $2 $3
}
#the parameter year is the actural year minus STARTOFLUNARYEAR
function _lunarDayToNumber {
_yr=$1
_mn=$2
_dy=$3
_days=`_lunarDaysInYear $_yr $_mn $_dy`
while [ $_yr -gt 0 ] ; do
((_yr=_yr-1))
((_days=_days+`_lunarDaysOfYear $_yr`))
#echo $_days `_lunarDaysOfYear $_yr`
done
echo $((_days+BASENUMBER-1))
}# number of days to date
function numberToDay {
_days=$1
_yr=$((_days/DAYSINYEAR+STARTOFLUNARYEAR))
_days_in_year=$((_days-`dayToNumber $_yr 1 1`+1))
if [ $_days_in_year -lt 1 ] ; then
((_yr=_yr-1))
_days_in_year=$((_days-`dayToNumber $_yr 1 1`+1))
fi
#echo $_days_in_year $_yr
_mn=1
#January is 31
_days_in_month=31
while [ $_days_in_year -gt $_days_in_month ] ; do
# echo $_days_in_year $_days_in_month $_mn
((_days_in_year=_days_in_year-_days_in_month))
((_mn=_mn+1))
if [ $_mn == 13 ] ; then
((_yr=_yr+1))
_mn=1
fi
_days_in_month=`daysOfMonth $_yr $_mn`
done
echo $_yr $_mn $_days_in_year
}# number of days to date in lunar
function lunarNumberToDay {
_days=$1
_yr=$((_days/DAYSINYEAR))
#echo $_yr $_days $DAYSINYEAR
_days_in_year=$((_days-`_lunarDayToNumber $_yr 1 1`+1))
#echo $_days_in_year $_yr
if [ $_days_in_year -lt 1 ] ; then
((_yr=_yr-1))
_days_in_year=$((_days-`_lunarDayToNumber $_yr 1 1`+1))
fi
#echo $_days_in_year $_yr
_mn=1
_days_in_month=`_lunarDaysOfMonth $_yr $_mn`
_lp_mn=`_lunarLeapMonth $_yr`
_leaping=""
#echo leap $_lp_mn
#_lp_mn_dys=`_lunarDaysOfLeapMonth $_yr`
while [ $_days_in_year -gt $_days_in_month ] ; do
# echo $_days_in_year $_days_in_month $_mn
((_days_in_year=_days_in_year-_days_in_month))
if [ $_mn == $_lp_mn -a "$_leaping" == "" ] ; then
_leaping="(leap)"
_days_in_month=`_lunarDaysOfLeapMonth $_yr`
else
_leaping=""
((_mn=_mn+1))
if [ $_mn == 13 ] ; then
((_yr=_yr+1))
_mn=1
_lp_mn=`_lunarLeapMonth $_yr`
fi
_days_in_month=`_lunarDaysOfMonth $_yr $_mn`
fi
done
echo $((_yr+STARTOFLUNARYEAR)) $_mn$_leaping $_days_in_year
}#solar date to lunar date
function day2Lunar {
if [ $# == 0 ] ; then
_date=`date +"%Y %m %d"`
else
_date="$*"
fi
lunarNumberToDay `dayToNumber $_date`
}
#same as day2Lunar
function d2l {
day2Lunar $*
}#test only
function _day2Day {
numberToDay `dayToNumber $*`
}#lunar date to solar date
function lunar2Day {
numberToDay `lunarDayToNumber $*`
}#same as lunar2Day
function l2d {
numberToDay `lunarDayToNumber $*`
}#test only
function _lunar2Lunar {
lunarNumberToDay `lunarDayToNumber $*`
}#help message
function help {
_d=`date +"%Y %m %d"`
cat <