编程语言
首页 > 编程语言> > 确切的Excel Days360算法是什么?

确切的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