【问题标题】:Find closest end-of-month for a given date in C#在 C# 中查找给定日期的最近月末
【发布时间】:2018-06-15 06:00:52
【问题描述】:

我想找到与特定日期“最接近”的月末日期。例如,如果日期是4.3.2017,则28.2.2017 是最接近的日期。对于20.3.201731.3.2017 是最接近的日期。对于陷入死角的日期,我们选择较低的日期还是较高的日期并不重要。

从这两个帖子中,How do I get the last day of a month?Find the closest time from a list of times,我已经能够将以下方法拼凑在一起

public static DateTime findNearestDate(DateTime currDate)
{
    List<DateTime> dates = new List<DateTime> { ConvertToLastDayOfMonth(currDate.AddMonths(-1)), ConvertToLastDayOfMonth(currDate) };
    DateTime closestDate = dates[0];
    long min = long.MaxValue;

    foreach (DateTime date in dates)
        if (Math.Abs(date.Ticks - currDate.Ticks) < min)
        {
            min = Math.Abs(date.Ticks - currDate.Ticks);
            closestDate = date;
        }
    return closestDate;
}

public static DateTime ConvertToLastDayOfMonth(DateTime date)
{
    return new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
}

这可行,但似乎有很多代码可以完成这样一个简单的任务。有人知道更简单、更紧凑的方法吗?

【问题讨论】:

    标签: c# datetime


    【解决方案1】:

    鉴于只能有两个选项,在这里循环似乎很奇怪。

    假设您只有日期,而不需要担心一天中的时间,在我看来,决定只取决于“当前”月份有多少天。所以像:

    // Names adjusted to follow .NET naming conventions
    public static DateTime FindNearestEndOfMonth(DateTime date)
    {
        int year = date.Year;
        int month = date.Month;
        int daysInMonth = DateTime.DaysInMonth(year, month);
        return date.Day >= daysInMonth / 2
            // End of current month
            ? new DateTime(year, month, daysInMonth)
            // End of previous month
            : new DateTime(year, month, 1).AddDays(-1);
    }
    

    【讨论】:

    • 不错!紧凑得多。不需要我的辅助方法 ConvertToLastDayOfMonth :)
    【解决方案2】:

    您可以计算当前和上个月的最后日期并选择最接近的日期:

    public static DateTime GetNearestEOM(DateTime date)
    {
        DateTime EOMPrev = new DateTime(date.Year, date.Month, 1).AddDays(-1);
        DateTime EOMNext = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
        DateTime NearestEOM = (date - EOMPrev).TotalDays < (EOMNext - date).TotalDays ? EOMPrev : EOMNext;
        return NearestEOM;
    }
    
    GetNearestEOM(new DateTime(2017, 3, 4));  // 2017-02-28 00:00:00
    GetNearestEOM(new DateTime(2017, 3, 20)); // 2017-03-31 00:00:00
    

    【讨论】:

    • 谢谢。这也是一个不错的紧凑型解决方案。
    【解决方案3】:

    不需要循环。您可以使用框架内置的时间跨度添加功能:

    var closestendofmonth = new DateTime(date.Year, date.Month, 1).AddDays(-1);
    

    【讨论】:

    • 不过,这总是会返回上个月的月底 - 这不是 OP 想要的。
    • 我什至无法像您输入完整、正确的答案一样快速思考 :)
    猜你喜欢
    • 1970-01-01
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 2021-03-30
    • 1970-01-01
    • 2018-06-04
    相关资源
    最近更新 更多