16

只是想知道是否有人知道以下的优雅解决方案。

如果我有 2009 年 6 月 30 日并且我添加了一个月,我希望它转到 2009 年 7 月 31 日,而不是 2009 年 7 月 30 日。

这个逻辑是基于这样一个事实,即 2009 年 6 月 30 日是 6 月的月底,当我添加一个月时,我想去下个月的月底。

但是,如果我有 2009 年 6 月 29 日并且我添加了一个月,它应该是 2009 年 7 月 29 日。

注意我需要能够添加任意数量的月份,并且需要考虑闰年。

我也知道这里的逻辑是有问题的,但这是一项业务需求,适用于未来一个月的月底合同。

我已经想到了几种解决方案,但没有一个非常优雅。因此,我认为有人可能有更好的方法。

干杯安东尼

4

10 回答 10

37

要检查某个日期是否是月底,请检查第二天是否是某个月的第一天。你的算法应该是“如果一天不是月底,加 1 个月。如果是月底,加一天,加一个月,减一天。”

    bool IsEndOfMonth(DateTime date) {
        return date.AddDays(1).Day == 1;
    }
    DateTime AddMonthSpecial(DateTime date) {
        if (IsEndOfMonth(date))
            return date.AddDays(1).AddMonths(1).AddDays(-1);
        else
            return date.AddMonths(1);
    }
于 2009-06-11T02:05:34.390 回答
2
DateTime exampleDate = DateTime.Parse("12/31/2009");
bool isLastDayOfMonth = (exampleDate.AddDays(1).Month != exampleDate.Month);

if (isLastDayOfMonth)
    Console.WriteLine(exampleDate.AddDays(1).AddMonths(1).AddDays(-1));
else
    Console.WriteLine(new DateTime(exampleDate.Year, exampleDate.Month, 1).AddMonths(2).AddDays(-1));

编辑:我又读了你的问题。您将需要检查它是否是该月的最后一天。

对不起,我希望我已经清楚地阅读了需要什么的问题。
希望这足以让您了解需要什么。

于 2009-06-11T02:15:50.717 回答
1

您可以从上个月的第一天开始并返回一天吗?

于 2009-06-11T02:05:43.110 回答
0
  1. 测试以查看旧日期是否为“月末”。
    1. 将日期添加到日期,然后查看月份编号是否更改。
  2. 添加一个月
  3. 如果旧日期是“月末”
    1. 将日期设置为 1
    2. 再增加一个月
    3. 减去一天
于 2009-06-11T02:08:37.753 回答
0

我解决这个问题的方法是从确定某一天是否是该月的最后一天的例程开始(当然要考虑闰年的二月!)

你还需要一个例程,给你一个月的最后一天,给你那个月的一天。

然后,如果您遇到的一天是最后一天,则添加一天,并使用第二个例程获取该月的最后一天。使用循环数月。

于 2009-06-11T02:10:29.200 回答
0

您可以实现 EndOfMonth() 和 isEndOfMonth()。

所以你的代码或多或少是,

if isEndOfMonth( this.Date() )
  endDate = (startmonth + addedMonths).EndOfMonth()
else
  endDate = startDate + addedMonths

有点简单,但你明白了。

对于 EndOFMonth 和 isEndOfMonth 的逻辑,这里当然有很多想法

于 2009-06-11T02:12:34.063 回答
0

这是一个简单的 .NET C# 解决方案,适用于闰年等:

static DateTime ContractDue(DateTime start, int months)
{
     if (start.Month == start.AddDays(1).Month)
     { // Same month, just add the months
            return start.AddMonths(months);
     }
     // Last day of month... add a day, add the months, then go back one day
     return start.AddDays(1).AddMonths(months).AddDays(-1);
}
于 2009-06-11T02:18:41.100 回答
0

您可以使用 DateTime.DaysInMonth() 方法,如下所示:

DateTime workingMonth = new DateTime(2009, 06, 30).AddDays(1);
int nextMonthDays = DateTime.DaysInMonth(workingMonth.Year, workingMonth.Month);
DateTime newMonth = new DateTime(workingMonth.Year, workingMonth.Month, nextMonthDays);
于 2009-06-11T04:19:31.220 回答
0

如果我在月初,这会是补充函数吗? DateTime.Now.AddDays(-1).Month == DateTime.Now.AddMonths(-1).Month

于 2014-01-16T11:57:18.843 回答
-1

如果您只需要 EndOfMonth 或简单的 AddNMonth,那么您已经得到了答案。

否则,要获得完整的通用解决方案,您将需要实现 Recurrence 模式,您可能会在Outlook 会议界面的 UI 中看到它。虽然我不建议您使用 Outlook 实现,但应该有一些您可以购买的 .NET 组件。或者自己实现它,但不要低估它并对其进行单元测试 - 这是一个非常棘手的实现组件。

于 2009-06-11T04:06:14.773 回答