interface
uses sysutils;
type TCNDate = Cardinal;
function DecodeGregToCNDate(dtGreg:TDateTime):TCNDate;
function GetGregDateFromCN(cnYear
TDateTime;
function GregDateToCNStr(dtGreg:TDateTime):String;
function isCNLeap(cnDate:TCNDate):boolean;
implementation
const cstDateOrg:Integer=
const cstCNYearOrg=
const cstCNTable:array[cstCNYearOrg
unsigned
//
//建表方法
//
天
//閏月一般算小月
//對於特例則高四位的閏月位置表示法中的最高為設置為
量
// //
//如果希望用匯編
//將公歷轉換為農歷
//返回:
function DecodeGregToCNDate(dtGreg:TDateTime):TCNDate;
var
iDayLeave:Integer;
wYear
i
wBigSmallDist
label OK;
begin
result :=
iDayLeave := Trunc(dtGreg)
DecodeDate(IncMonth(dtGreg
if (iDayLeave <
//Raise Exception
//Raise Exception
for i:=Low(cstCNTable) to High(cstCNTable) do begin
wBigSmallDist := cstCNTable[i];
wLeap := wBigSmallDist shr
if wLeap >
wLeap := wLeap and
wLeapShift :=
end else
wLeapShift :=
for j:=
wCount:=(wBigSmallDist and
if j=wLeap then wCount := wCount
if iDayLeave < wCount then begin
Result := (i shl
Exit;
end;
iDayLeave := iDayLeave
if j=wLeap then begin
wCount:=
if iDayLeave < wCount then begin
Result := (i shl
Exit;
end;
iDayLeave := iDayLeave
end;
wBigSmallDist := wBigSmallDist shr
end;
end;
//返回值:
//
end;
function isCNLeap(cnDate:TCNDate):boolean;
begin
result := (cnDate and $
end;
function GetGregDateFromCN(cnYear
TDateTime;
var
i
DayCount:integer;
wBigSmallDist
begin
//
DayCount :=
if (cnYear <
Result :=
Exit;
end;
for i:= cstCNYearOrg to cnYear
wBigSmallDist := cstCNTable[i];
if (wBIgSmallDist and $F
DayCount := DayCount +
for j:=
DayCount := DayCount + wBigSmallDist and
wBigSmallDist := wBigSmallDist shr
end;
end;
wBigSmallDist := cstCNTable[cnYear];
wLeap := wBigSmallDist shr
if wLeap >
wLeap := wLeap and
wLeapShift :=
end else
wLeapShift :=
for j:=
DayCount:=DayCount + (wBigSmallDist and
if j=wLeap then DayCount := DayCount +
wBigSmallDist := wBigSmallDist shr
end;
if bLeap and (cnMonth = wLeap) then //是要閏月的嗎?
DayCount := DayCount +
result := cstDateOrg + DayCount + cnDay
end;
//將日期顯示成農歷字符串
function GregDateToCNStr(dtGreg:TDateTime):String;
const hzNumber:array[
function ConvertYMD(Number:Word;YMD:Word):string;
var
wTmp:word;
begin
result :=
if YMD =
while Number >
result := hzNumber[Number Mod
Number := Number DIV
end;
Exit;
end;
if Number<=
if YMD =
result := hzNumber[Number]
else //天
result :=
Exit;
end;
wTmp := Number Mod
if wTmp <>
wTmp := Number Div
result:=
if wTmp >
end;
var
cnYear
cnDate:TCNDate;
strLeap:string;
begin
cnDate:= DecodeGregToCNDate(dtGreg);
if cnDate =
result :=
Exit;
end;
cnDay := cnDate and $
cnMonth := (cnDate shr
cnYear := (cnDate shr
//測試第
if isCNLeap(cnDate) then strLeap:=
result :=
+ strLeap + ConvertYMD(cnDay
end;
end
From:http://tw.wingwit.com/Article/program/Delphi/201311/25056.html