qq:184237867
//wwl的計算方法begin
DecodeDate(dDate,AYear, AMonth, ADay);
DecodeDate(Now,AYear2, AMonth2, ADay2);
iYear:=YearsBetween(Now,dDate);
nMonth:=MonthsBetween(Now,dDate);
nday:=DaysBetween(Now,dDate);
iYear:=nMonth div 12;//相差年份
if nMonth>12 then
AYear:=AYear+iYear;
dDate:=EncodeDate(AYear,AMonth,ADay);
nMonth:=MonthsBetween(Now,dDate);//相差月份
iMonth:=nMonth;//剩下月份
if nMonth<12 then
if nMonth<12-AMonth then
AMonth:=AMonth+nMonth;
if nMonth>12-AMonth then
begin
AMonth:=nMonth-(12-AMonth);
if AMonth>12 then
AMonth:=AMonth-12;
AYear:=AYear+1;
end;
dDate:=EncodeDate(AYear,AMonth,ADay);
iDay:=DaysBetween(Now,dDate);
if AYear>3000 then
AYear:=AYear2;
if AMonth>=12 then
AMonth:=0;
if ADay>30 then
ADay:=0;
if iMonth<0 then
iMonth:=0;
if iDay<0 then
iDay:=0;
//wwl的計算方法end
uj5u.com熱心網友回復:
你這個有問題:1、月份天數不是固定的,這樣,不能確定X月數。
2、只能如果從Now,向后推,扣整年數后,天數,再推廣剩下的月數、天數。
uj5u.com熱心網友回復:
演算法應該是這樣的,先比較年份,得到年份的差值,比如nYear,判斷條件是>=0,否則彈出日期錯誤;再比較月份,得到nMonth,如果月份>=0,直接比較天數;否則看nYear是否>=1,<1彈出日期錯誤;>=1,nYear減1,nMonth+12;再比較天數,如果nDay>=0,得出結論,否則,nMonth-1,nDay+上個月的天數;uj5u.com熱心網友回復:
比較天數如果為負,同樣要判斷月份,年份夠不夠扣,如果在拆年月日之前就判斷過了,就無需判斷了uj5u.com熱心網友回復:
procedure TForm1.Button1Click(Sender: TObject);
var
dDate: TDateTime;
AYear, AMonth, ADay, AYear2, AMonth2, ADay2: Word;
iYear, iMonth, iDay, nMonth, nday: Integer;
begin
dDate := DateTimePicker1.DateTime;
if dDate > Now then
Exit;
DecodeDate(dDate, AYear, AMonth, ADay);
DecodeDate(Now, AYear2, AMonth2, ADay2);
iYear := AYear2 - AYear;
iMonth := AMonth2 - AMonth;
if iMonth < 0 then
begin
iYear := iYear - 1;
iMonth := iMonth + 12;
end;
iDay := ADay2 - ADay;
if iDay < 0 then
begin
iMonth := iMonth - 1;
if iMonth < 0 then
begin
iYear := iYear - 1;
iMonth := iMonth + 12;
iDay:=ADay2;
end;
end;
if (iYear = 0) and (iMonth = 0) then
iDay:= DaysBetween(Now, dDate);
Edit1.Text := Format('%d歲%d月%d天', [iYear, iMonth, iDay]);
// iYear := YearsBetween(Now, dDate);
// nMonth := MonthsBetween(Now, dDate);
// nday := DaysBetween(Now, dDate);
// iYear := nMonth div 12; // 相差年份
// if nMonth > 12 then
// AYear := AYear + iYear;
//
// dDate := EncodeDate(AYear, AMonth, ADay);
// nMonth := MonthsBetween(Now, dDate); // 相差月份
// iMonth := nMonth; // 剩下月份
//
// if nMonth < 12 then
// if nMonth < 12 - AMonth then
// AMonth := AMonth + nMonth;
// if nMonth > 12 - AMonth then
// begin
//
// AMonth := nMonth - (12 - AMonth);
// if AMonth > 12 then
// AMonth := AMonth - 12;
// AYear := AYear + 1;
// end;
//
// dDate := EncodeDate(AYear, AMonth, ADay);
//
// iDay := DaysBetween(Now, dDate);
//
// if AYear > 3000 then
// AYear := AYear2;
//
// if AMonth >= 12 then
// AMonth := 0;
// if ADay > 30 then
// ADay := 0;
//
// if iMonth < 0 then
// iMonth := 0;
// if iDay < 0 then
// iDay := 0;
end;
uj5u.com熱心網友回復:
你的代碼,看過了。1、要考慮超過指定日,月數的累計
2、要考慮月的天數,2月份有26、27、28、29;單雙月有30、31天;
3、當月天數,要與實際統一起來。
uj5u.com熱心網友回復:
做出個玩具出來了,經測驗,接近完美unit UnitMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DateUtils, StdCtrls, ComCtrls;
type
TFormMain = class(TForm)
DateTimePicker1: TDateTimePicker;
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
procedure MyGetLunarHolDay;
private
{ Private declarations }
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
uses DateCn, UGL2NLdatae;
{$R *.dfm}
procedure TFormMain.MyGetLunarHolDay;
var
i: Integer;
s: string;
begin
s := GetLunarHolDay(DateTimePicker1.Date);
if s <> '' then
Label2.Caption := format('節氣:今天[%s]', [s])
else
begin
for i := 1 to 20 do
begin
s := GetLunarHolDay(DateTimePicker1.Date - i);
if s <> '' then
begin
Label2.Caption := format('節氣:當天 [%s] 第 %d 天', [s, i + 1]);
Break;
end;
end;
end;
for i := 1 to 20 do
begin
s := GetLunarHolDay(DateTimePicker1.Date + i);
if s <> '' then
begin
Label3.Caption := format('下一節氣:[%s] %d 天后', [s, i]);
Break;
end;
end;
end;
procedure TFormMain.Button1Click(Sender: TObject);
var
dDate, dDateTarg: TDateTime;
AYear, AMonth, ADay, AYear2, AMonth2, ADay2: Word;
iYear, iMonth, iDay, nMonth, nDay, iBirthDay: Integer;
begin
dDate := DateTimePicker1.DateTime;
dDateTarg := Trunc(Now);
DecodeDate(dDate, AYear, AMonth, ADay);
DecodeDate(dDateTarg, AYear2, AMonth2, ADay2);
if (AYear > 1900) and (AYear <= 2050) then
begin
Label1.Caption := format('農歷:%s', [CnDateOfDateStr(DateTimePicker1.Date)]);
MyGetLunarHolDay;
end
else
Label1.Caption := format('農歷:%s', ['超出查詢范圍!']);
if dDate > Now then
begin
Edit1.Text := '日期非法,出生日期大于當前日期';
Edit2.Text := format('距離當前時間:%d天', [DaysBetween(dDateTarg, Trunc(DateTimePicker1.Date))]);
Exit;
end;
iYear := AYear2 - AYear; // 計算歲數
iMonth := AMonth2 - AMonth; // 相差月份
if iMonth < 0 then
begin
iYear := iYear - 1;
iMonth := iMonth + 12;
end;
iDay := ADay2 - ADay; // 相差天數
if iDay < 0 then
begin
iMonth := iMonth - 1;
if iMonth < 0 then
begin
iYear := iYear - 1;
iMonth := iMonth + 12;
end;
if AMonth2 = 1 then
nMonth := 12
else
nMonth := AMonth2 - 1;
nDay := DayOfTheMonth(EndOfTheMonth(EncodeDate(AYear, nMonth, 1)));
if ADay > nDay then
iDay := ADay2
else
iDay := ADay2 + nDay - ADay;
end;
// iDay := ADay2 - ADay;
// if iDay < 0 then
// begin
// iMonth := iMonth - 1;
// if iMonth < 0 then
// begin
// iYear := iYear - 1;
// iMonth := iMonth + 12;
// iDay:=ADay2;
// end;
// end;
//
// if (iYear = 0) and (iMonth = 0) then
// iDay:= DaysBetween(dDateTarg, dDate);
Edit1.Text := format('%d歲%d月%d天', [iYear, iMonth, iDay]);
// 計算距離生日的天數
if (AMonth = 2) and (ADay = 29) then // 2月29日特殊處理
begin
if (AYear2 mod 4) = 0 then
begin
if EncodeDate(AYear2, AMonth, ADay) >= Trunc(dDateTarg) then
iBirthDay := DaysBetween(dDateTarg, EncodeDate(AYear2, AMonth, ADay))
else
iBirthDay := DaysBetween(dDateTarg, EncodeDate(AYear2 + 4, AMonth, ADay));
end
else
begin
iBirthDay := DaysBetween(dDateTarg, EncodeDate(AYear2 + 4 - (AYear2 mod 4), AMonth, ADay));
end;
end
else
begin
if EncodeDate(AYear2, AMonth, ADay) >= Trunc(dDateTarg) then
iBirthDay := DaysBetween(dDateTarg, EncodeDate(AYear2, AMonth, ADay))
else
iBirthDay := DaysBetween(dDateTarg, EncodeDate(AYear2 + 1, AMonth, ADay));
end;
Edit2.Text := format('距離生日%d天', [iBirthDay]);
end;
end.
uj5u.com熱心網友回復:
.....
nDay := DayOfTheMonth(EndOfTheMonth(EncodeDate(AYear, nMonth, 1)));
//-------------如果上月的天數比生日的天數少,則取0,如果實在糾結這幾天,可以把下面代碼換成iDay := ADay2 +abs( nDay - ADay);
if ADay > nDay then
iDay := ADay2
else
iDay := ADay2 + nDay - ADay;
//---------
end;
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/44317.html
標籤:VCL組件開發及應用
上一篇:類和介面的問題
