确切的Excel Days360算法是什么?
作者:互联网
我正在将使用Days360函数(默认/美国方法)的一些计算从Excel移植到C#.使用Wikipedia page作为指导,我想到了以下代码:
public static int Days360(DateTime a, DateTime b)
{
var dayA = a.Day;
var dayB = b.Day;
if (IsLastDayOfFebruary(a) && IsLastDayOfFebruary(b))
dayB = 30;
if (dayA == 31 || IsLastDayOfFebruary(a))
dayA = 30;
if (dayA == 30 && dayB == 31)
dayB = 30;
return ((b.Year - a.Year) * 12 + b.Month - a.Month) * 30 + dayB - dayA;
}
private static bool IsLastDayOfFebruary(DateTime date)
{
if (date.Month != 2)
return false;
int lastDay = DateTime.DaysInMonth(date.Year, 2);
return date.Day == lastDay;
}
我使用(少量)输入范围进行了测试,结果除与a和b均使用2015-02-28之外,其他结果基本上与Excel的本机函数一致.我的代码返回0和Excel -2.
我的结果似乎更合理,但在这一点上,我希望计算与Excel完全相同的结果.他们可能会有其他意见分歧,因此我不想仅针对该日期提出特殊情况.
有谁知道Excel使用的确切算法?
编辑:我张贴的原始代码中有一个明显的错误,与问题无关.我已经解决了那个问题,但是在发布问题时从错误的文件中复制了内容.
解决方法:
根据this Wikipedia article,Microsoft Excel Days360函数等效于30/360 BMA / PSA.因此,要获得如MS Excel一样的准确结果,我们需要实现BMA / PSA方法.我已经实现了该方法.
private double Days360(DateTime StartDate, DateTime EndDate)
{
int StartDay = StartDate.Day;
int StartMonth = StartDate.Month;
int StartYear = StartDate.Year;
int EndDay = EndDate.Day;
int EndMonth = EndDate.Month;
int EndYear = EndDate.Year;
if (StartDay == 31 || IsLastDayOfFebruary(StartDate))
{
StartDay = 30;
}
if (StartDay == 30 && EndDay == 31)
{
EndDay = 30;
}
return ((EndYear - StartYear) * 360) + ((EndMonth - StartMonth) * 30) + (EndDay - StartDay);
}
private bool IsLastDayOfFebruary(DateTime date)
{
return date.Month == 2 && date.Day == DateTime.DaysInMonth(date.Year, date.Month);
}
标签:c,excel,algorithm,vba,excel-vba 来源: https://codeday.me/bug/20191120/2043205.html