這兩個過程是在應用單元中的,必須包含一個先成的單元calfunc.unit ,該單元的功能是將公曆轉農曆的.代碼太多貼不出來.
先說下這個算法的大概思路:
單元calfunc.unit中有個函數CnMonthStr,CnDayStr,CnDateOfDateStr都是對應的公曆轉農曆的.利用公共單元可以從公曆獲得農曆.然後將當前輸入的農曆帶入NDateToGDate函數中,作爲公曆求農曆,一直將農曆網後加一天,直到獲得的農曆和輸入的公曆的農曆相同爲止.這句話比較難懂,暫時不用去想是怎麼回事,弄個圖抽象出來會比較好懂點:
INPUT:我們輸入的農曆
CNINP:根據輸入的農曆(作爲公曆)獲得的農曆
VDATE:我們目標要獲得的公曆
CDATE:目標公曆對應的農曆這個值和INPUT一開始是相等的(爲什麼?因爲我強制讓他的初值相等)
----------------------------------------INPUT--------------------------------------
CNINP------------------------------------------------------------------------------
------------------------------------------------------------------------------VDATE
----------------------------------------CDATE-------------------------------------
上面這個是抽象圖,我們的目的就是輸入INPUT獲得VDATE,輸入INPUT可以得到CNINP,如果想要INPUT=VDATE,那麼就要讓CNINP=CDATE,而且一開始的時候INPUT和CDATE是相等的.這樣就可以做一個平移了.一直加INPUT的天數,一直到CNINP和CDATE相等的時候就可以獲得我們所要求的VDATE了.在這個平移的過程中要考慮上月份,因爲回有跨月的時候出現,但是不必要帶上年份,因爲就算跨年,只要比較平移獲得的月日相同,目標公曆還是不變的.
- procedure TFrmOrder.LDateToGDateClick(Sender: TObject);
- var
- vDate : TDate;
- begin
- vDate :=NDateToGDate(CmbYear.text,CmbMonth.text,Cmbday.text);
- CmbYear.Text := inttostr(YearOf(vDate));
- CmbMonth.Text := inttostr(MonthOf(vDate));
- Cmbday.Text := inttostr(DayOf(vDate));
- LDateToGDate.Enabled := False;
- end;
- function NDateToGDate(LYear,LMonth,LDay:string):TDate;
- const
- CnMonthStr: array[1..12] of String = (
- '一', '二', '三', '四', '五', '六', '七', '八', '九', '十',
- '冬', '臘');
- CnDayStr: array[1..30] of String = (
- '初一', '初二', '初三', '初四', '初五',
- '初六', '初七', '初八', '初九', '初十',
- '十一', '十二', '十三', '十四', '十五',
- '十六', '十七', '十八', '十九', '二十',
- '廿一', '廿二', '廿三', '廿四', '廿五',
- '廿六', '廿七', '廿八', '廿九', '三十');
- var
- vDate : TDate;
- vDateStr : string;
- vMonth,vDay,LDate :string;
- begin
- Result := Now(); //初始化
- try
- vDate := strtoDate(LYear+'-'+LMonth+'-'+LDay);
- vMonth := CnMonthStr[strtoint(LMonth)]+'月';
- vDay := CnDayStr[strtoint(LDay)];
- LDate := vMonth+vDay;
- While not (LDate = vDateStr) do
- begin
- vDateStr := CnDateOfDateStr(vDate);
- vDate := vDate+1;
- end;
- vDate := vDate - 1;
- Result := vDate;
- except
- on e: exception do
- begin
- Application.MessageBox(Pchar('格式有錯誤,請將農曆改成阿拉伯數字填在相應位置'),'系統提示',MB_OK);
- Exit;
- end;
- end;
- end;
小結
在C#中有這個類:System.Globalization.ChineseLunisolarCalendar可以直接從農曆獲得公曆,真是太方便了.
參考MSDN:http://msdn.microsoft.com/zh-cn/library/system.globalization.chineselunisolarcalendar(VS.80).aspx