歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> SHELL編程

Linux shell實現陽歷轉農歷

Linux shell實現陽歷轉農歷   閒來無事,想在Linux下用shell寫一個陽歷轉農歷的腳本,斷斷續續大概一個星期終於搞定。現在拿出來與大家分享。   本腳本實現原理是查表法(因為公式有誤差);基於農歷新年為基准,對農歷新年前後兩個不同的農歷進行計算。   寫這個腳本之前是想在Linux 終端命令提示符中加入陽歷及農歷日期。在Ubuntu中有Lunar軟件可以獲取農歷日期,但在Fedora或CentOS中並沒有類似軟件,所以就想自己來實現一個,但網上用其他語言寫的一大把,如果再寫沒什麼必要。所以就想用shell來寫一個。   功能:將具體的陽歷日期轉換為農歷日期。   時間范圍:1901~2099,對應農歷年時間為4598~4796   參數格式(無參數默認為當前系統日期):yyyymmdd   如2013年1月1日:   $./lunar.sh 20130101   4709-11-20   完整數據下載地址:   http://up.2cto.com/2013/0716/20130716104840753.rar   包中文件:   lunar.sh 主腳本,具體實現   datebases 農歷元數據   change.log 更改日志   readme 腳本說明及注意事項   主要腳本lunar.sh代碼如下:   #!/bin/sh   DATE=$@ [ "$DATE" = "" ] && DATE=$(date +%Y%m%d)   date_year=$(echo $DATE |sed 's/^\(.\{4\}\).*/\1/') date_month=$(echo $DATE |sed 's/.*\(..\)..$/\1/') date_day=$(echo $DATE |sed 's/.*\(..\)$/\1/') date_days=$(date -d $DATE +%j)   lunar_year=$(sed /$date_year/!d databases |sed 's/^\(....\).*/\1/')   lunar_year_data=$(sed /$date_year/!d databases |sed 's/.*\ \(.*\)/\1/') lunar_year_data_bin=$(echo "ibase=16;obase=2;$lunar_year_data"|bc |sed -e :a -e 's/^.\{1,23\}$/0&/;ta')   new_year_month_bin=$(echo $lunar_year_data_bin |sed -e 's/^.\{17\}\(.\{2\}\).*/\1/') new_year_month=$(echo "ibase=2;$new_year_month_bin"|bc |sed -e :a -e 's/^.\{1,1\}$/0&/;ta')   new_year_day_bin=$(echo $lunar_year_data_bin |sed -e 's/.*\(.\{5\}\)$/\1/') new_year_day=$(echo "ibase=2;$new_year_day_bin"|bc |sed -e :a -e 's/^.\{1,1\}$/0&/;ta')   new_year_days=$(date -d $date_year$new_year_month$new_year_day +%j)   lunar_days=$(expr $date_days - $new_year_days + 1)   befor_or_after=0   if [ "$lunar_days" -le "0" ]; then    befor_or_after=1    date_year=$(($date_year-1))      lunar_year=$(sed /$date_year/!d databases |sed 's/^\(....\).*/\1/')      lunar_year_data=$(sed /$date_year/!d databases |sed 's/.*\ \(.*\)/\1/')    lunar_year_data_bin=$(echo "ibase=16;obase=2;$lunar_year_data"|bc |sed -e :a -e 's/^.\{1,23\}$/0&/;ta') fi   lunar_leap_month_bin=$(echo $lunar_year_data_bin |sed -e 's/^\(.\{4\}\).*/\1/') lunar_leap_month=$(echo "ibase=2;$lunar_leap_month_bin"|bc)   lunar_month_all_bin=$(echo $lunar_year_data_bin |sed -e 's/^.\{4\}\(.\{13\}\).*/\1/') [ "$lunar_leap_month" = "0" ] && lunar_month_all_bin=$(echo $lunar_year_data_bin |sed -e 's/^.\{4\}\(.\{12\}\).*/\1/') lunar_month_all=$(echo $lunar_month_all_bin |sed -e 's/0/29\ /g' |sed -e 's/1/30\ /g')   if [ "$befor_or_after" = "0" ];then    lunar_month=1    lunar_day=$lunar_days    for i in $lunar_month_all    do       if [ "$lunar_day" -gt "$i" ]; then          lunar_day=$(($lunar_day - $i))          lunar_month=$(($lunar_month + 1))       fi    done else    lunar_month=12    lunar_day=$((-$lunar_days))    lunar_month_all_bin=$(echo $lunar_month_all_bin |rev)    lunar_month_all=$(echo $lunar_month_all_bin |sed -e 's/0/29\ /g' |sed -e 's/1/30\ /g')    for i in $lunar_month_all    do       if [ "$lunar_day" -gt "$i" ]; then          lunar_day=$(($lunar_day - $i))          lunar_month=$(($lunar_month - 1))       else          lunar_day=$(($i - $lunar_day))          break       fi    done fi   if [ "$lunar_leap_month" = "0" ]; then     echo $lunar_year-$lunar_month-$lunar_day else    if [ "$lunar_leap_month" -ge "$lunar_month" ]; then       echo $lunar_year-$lunar_month-$lunar_day    elif [ "$befor_or_after" = "0" ]; then       if [ "$(($lunar_leap_month + 1))" = "$lunar_month" ];then          lunar_month=$(($lunar_month - 1))          echo $lunar_year-*$lunar_month-$lunar_day       else          lunar_month=$(($lunar_month - 1))          echo $lunar_year-$lunar_month-$lunar_day       fi    else       echo $lunar_year-$lunar_month-$lunar_day    fi fi  
Copyright © Linux教程網 All Rights Reserved