Расчеты на конец месяца

Просто интересно, знаете ли какие-нибудь изящное решение для следующего.

Если у меня есть 30 июня 2009 года, и я добавлю месяц, я хочу, чтобы он перешел к 31 июля 2009 года, а не 30 июля 2009 года.

Эта логика основана на том, что 30 июня 2009 года был конец месяца июня, и когда я добавляю месяц, я хочу пойти в конец следующего месяца.

Но если у меня есть 29 июня 2009 года, и я добавлю месяц, он должен пойти до 29 июля 2009 года.

Примечание. Мне нужно иметь возможность добавлять любое количество месяцев, и мне нужно учитывать високосные годы.

Также я знаю, что логика здесь сомнительна, но это бизнес-требование, которое работает с контрактами конца месяца, которые будут отправляться в конце месяца на месяц в будущем.

Я подумал о нескольких решениях, но никто из них не очень изящный. Поэтому я думал, что у кого-то может быть лучший способ.

Приветствия Энтони

Ответы

Ответ 1

Чтобы проверить, соответствует ли дата концу месяца, вы проверяете, является ли следующий день одним днем ​​месяца. ваш алгоритм должен быть "Если день не конец месяца, добавьте 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);
    }

Ответ 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));

EDIT: Я снова прочитал ваш вопрос. Вам нужно будет поставить чек, чтобы узнать, есть ли его последний день месяца.

Извините, мне жаль, что я не прочитал вопрос о том, что нужно.
Надеюсь, это достаточно хорошо, чтобы дать вам представление о том, что нужно.

Ответ 3

Вы можете добраться туда, начиная с первого дня предыдущего месяца и возвращаясь однажды?

Ответ 4

  • Проверьте, не установлена ​​ли старая дата "конец месяца".
    • Добавьте день к дате и посмотрите, изменяется ли номер месяца.
  • Добавить месяц
  • Если старая дата была "end-of-month",
    • Установите день месяца на 1
    • Добавить еще месяц
    • Вычесть один день

Ответ 5

Мой подход к этой проблеме начнется с того, что будет выполняться рутина, определяющая, является ли данный день последним днем ​​месяца (с учетом летнего года, февраль, конечно!)

Вам также понадобится процедура, которая даст вам последний день месяца, учитывая день в этом месяце.

Затем, если вы встретите день, который является последним днем, добавьте один день и используйте вторую процедуру, чтобы получить последний день этого месяца. Используйте цикл в течение нескольких месяцев.

Ответ 6

Вы можете реализовать EndOfMonth() и isEndOfMonth().

чтобы ваш код был, более или менее,

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

Немного упрощен, но вы получаете идею.

Здесь, конечно, много идей для логики EndOFMonth и isEndOfMonth

Ответ 7

Вот простое решение .NET С#, которое рассчитано на високосные годы и т.д.:

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);
}

Ответ 8

Вы можете использовать метод 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);

Ответ 9

Будет ли эта функция дополнять, если я нахожусь в начале месяца? DateTime.Now.AddDays(-1).Month == DateTime.Now.AddMonths(-1).Month

Ответ 10

Если вам нужен только EndOfMonth или простой AddNMonth, вы уже получили свой ответ.

В противном случае, чтобы иметь полное общее решение, вам понадобится реализация шаблона Recurrence, поскольку вы можете увидеть его в пользовательском интерфейсе Интерфейс Outlook Meeting. Я не предлагаю вам использовать реализацию Outlook, но должно быть несколько компонентов .NET, которые вы можете купить. Или реализовать его самостоятельно, но не стоит недооценивать и тестировать все - это очень сложный компонент для реализации.