如何计算给定日期的满月百分比?

huangapple go评论75阅读模式
英文:

How can i calculate the percent of full moon on a given date?

问题

我需要找到给定日期的满月百分比,但我无法计算出来。我的尝试是错误的,因为今天的百分比约为96.9%。有人能看出我在Delphi代码中做错了什么吗?

procedure TfrmLag.btnCalcClick(Sender: TObject);
var
  whatDate    : TDateTime;      // 当前日期时间;
  lunarDays   : Double;        // 月相周期(天);
  lunarSecs   : LongInt;        // 月相周期(秒);
  new2000     : TDateTime;      // 2000年1月6日18时14分的日期时间;
  totalSecs   : LongInt;        // 当前日期时间与2000年1月6日18时14分的秒数差;
  currSecs    : LongInt;        // 当前秒数相对于月相周期的秒数;
  currFrac    : Double;        // 当前秒数相对于月相周期的分数;
  currDays    : LongInt;        // 当前分数相对于月相周期的天数;
  perOfFull   : Double;        // 满月百分比;
begin
  whatDate  := Now; // 获取当前日期时间
  lunarDays := 29.53058770576; // 月相周期(天)
  lunarSecs := Round(lunarDays * (24*60*60)); // 月相周期(秒)
  new2000   := EncodeDateTime(2000,1,6,18,14,00,000); // 2000年1月6日18时14分的日期时间
  totalSecs := SecondsBetween(whatDate, new2000); // 计算当前日期时间与2000年1月6日18时14分的秒数差
  currSecs  := totalSecs MOD lunarSecs; // 计算当前秒数相对于月相周期的秒数
  currFrac  := currSecs / lunarSecs; // 计算当前秒数相对于月相周期的分数
  currDays  := Round(currFrac*lunarDays); // 计算当前分数相对于月相周期的天数
  perOfFull := (100*currFrac); // 计算满月百分比

  lb.Items.Add('日期:'+FormatDateTime('dd.mm.yyyy hh:mm:ss',whatDate));
  lb.Items.Add('月相周期(秒):'+IntToStr(lunarSecs));
  lb.Items.Add('2000年第一个满月日期时间:'+FormatDateTime('dd.mm.yyyy hh:mm:ss',new2000));
  lb.Items.Add('总秒数差:'+IntToStr(totalSecs));
  lb.Items.Add('当前秒数:'+IntToStr(currSecs));
  lb.Items.Add('当前分数:'+FloatToStr(currFrac));
  lb.Items.Add('当前天数:'+IntToStr(currDays));
  lb.items.Add('满月百分比:'+FloatToStr(perOfFull));
end;
英文:

I need to find the percentage of a full moon on a given date, but i can not figure out how to calculate this. My attempt to do this is wrong, because the percent of to day is about 96.9%. Can anyone see what i'm doing wrong in my delphi-code.

procedure TfrmLag.btnCalcClick(Sender: TObject);
var
  whatDate    : TDateTime;      // Now;
  lunarDays   : Double;        // 29.53058770576
  lunarSecs   : LongInt;        // lunarDays * (24*60*60);
  new2000     : TDateTime;      // 6.1 2000 18:14
  totalSecs   : LongInt;        // whatDate - new2000
  currSecs    : LongInt;        // totalSecs MOD lunarSecs
  currFrac    : Double;        // currSecs / lunarSecs
  currDays    : LongInt;        // currFrac * lunarDays
  perOfFull   : Double;
begin
  whatDate  := Now;
  lunarDays := 29.53058770576;
  lunarSecs := Round(lunarDays * (24*60*60));
  new2000   := EncodeDateTime(2000,1,6,18,14,00,000);
  totalSecs := SecondsBetween(whatDate, new2000);
  currSecs  := totalSecs MOD lunarSecs;
  currFrac  := currSecs / lunarSecs;
  currDays  := Round(currFrac*lunarDays);
  perOfFull := (100*currFrac);


  lb.Items.Add('Date : '+FormatDateTime('dd.mm.yyyy hh:mm:ss',whatDate));
  lb.Items.Add('Lunar days : '+IntToStr(lunarSecs));
  lb.Items.Add('First full 2000 : '+FormatDateTime('dd.mm.yyyy hh:mm:ss',new2000));
  lb.Items.Add('Total seconds : '+IntToStr(totalSecs));
  lb.Items.Add('Current seconds : '+IntToStr(currSecs));
  lb.Items.Add('Current fraction : '+FloatToStr(currFrac));
  lb.Items.Add('Current days : '+IntToStr(currDays));
  lb.items.Add('Percent of full : '+FloatToStr(perOfFull));



end;

答案1

得分: 4

  • 我假设new2000是2000年的第一个新月?如果是这样的话,那么这段代码应该能正确计算。
  • 如果new2000是满月,你只需要在cos()函数中去掉-1
uses
	DateUtils;

procedure Calculate();
const
	MoonPeriod = 29.53058770576;
var
	KnownNewMoon: TDateTime;
	NowUTC: TDateTime;
	DaysSinceLastNewMoon, NumberOfNewMoons, MoonPart: Extended;
begin
	KnownNewMoon := EncodeDateTime(2000,1,6,18,14,00,000);
	NowUTC := TTimeZone.Local.ToUniversalTime(Now);
    
	//自从已知的新月日期以来,有多少个月相周期(新月->满月->新月)已经过去了?
	NumberOfNewMoons := (NowUTC - KnownNewMoon)/MoonPeriod;
	DaysSinceLastNewMoon := Frac(NumberOfNewMoons)*MoonPeriod;
    
	//“月相部分”是一个正弦/余弦函数,从新月开始为-0,满月时为1,然后在下一个新月时返回0。
	//从cos(-Pi)开始,将-1设置为“新月值”。添加1以将其设置为0。
	//满月是cos(0),再加上之前添加的1,我们需要除以2。
	MoonPart := (cos((NumberOfNewMoons*2 - 1) * Pi) + 1)/2;

	lb.items.Add('新月数量/数量:'+ FormatFloat('0.000000', NumberOfNewMoons));
	lb.items.Add('当前月相部分/位置:'+ FormatFloat('0.000000', MoonPart));
	lb.items.Add('距上一个新月的天数(包括小数部分):'+ FormatFloat('0.000000', DaysSinceLastNewMoon));
end;

这将给出MoonPart中可见的月相部分,以及距上一个新月的天数(包括小数部分)。

英文:
  • I suppose new2000 is the first new moon in the year 2000? If so then this code should calculate correctly.
  • If new2000 is the full moon, you only have to remove the -1 in the cos() function.
uses
	DateUtils;

procedure Calculate();
const
	MoonPeriod = 29.53058770576;
var
	KnownNewMoon: TDateTime;
	NowUTC: TDateTime;
	DaysSinceLastNewMoon, NumberOfNewMoons, MoonPart: Extended;
begin
	KnownNewMoon := EncodeDateTime(2000,1,6,18,14,00,000);
	NowUTC := TTimeZone.Local.ToUniversalTime(Now);
    
	//How many moon periods (new moon -> full moon -> new moon) have passed
	//since that known new moon date?
	NumberOfNewMoons := (NowUTC - KnownNewMoon)/MoonPeriod;
	DaysSinceLastNewMoon := Frac(NumberOfNewMoons)*MoonPeriod;
    
	//The "moon part" is a sine/cosine function that starts at new moon with -0,
	//reaches 1 at full moon and goes back to 0 at the next new moon.
	//Starting at cos(-Pi) gives a -1 as "new moon value". Add 1 to set this to 0.
	//Full moon is cos(0) gives 1. With the 1 added before, we have to divide by 2.
	MoonPart := (cos((NumberOfNewMoons*2 - 1) * Pi) + 1)/2;

	lb.items.Add('Number/amount of new moons: '+ FormatFloat('0.000000', NumberOfNewMoons));
	lb.items.Add('Current moon part/position: '+ FormatFloat('0.000000', MoonPart));
	lb.items.Add('Days since last new moon:   '+ FormatFloat('0.000000', DaysSinceLastNewMoon));
end;

This should give you the visible moon part in MoonPart and the days (incl. fraction) since the last new moon.

huangapple
  • 本文由 发表于 2023年1月9日 03:29:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75050682.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定