Расчеты на конец месяца - PullRequest
15 голосов
/ 11 июня 2009

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

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

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

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

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

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

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

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

Ответы [ 10 ]

34 голосов
/ 11 июня 2009

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

РЕДАКТИРОВАТЬ: я прочитал ваш вопрос еще раз. Вам нужно будет поставить чек, чтобы узнать, последний ли это день месяца.

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

1 голос
/ 11 июня 2009

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

0 голосов
/ 16 января 2014

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

0 голосов
/ 11 июня 2009

Вы можете использовать метод 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);
0 голосов
/ 11 июня 2009

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

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

0 голосов
/ 11 июня 2009

Вот простое решение .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);
}
0 голосов
/ 11 июня 2009

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

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

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

Немного упрощенно, но вы поняли.

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

0 голосов
/ 11 июня 2009

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

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

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

0 голосов
/ 11 июня 2009
  1. Проверьте, является ли старая дата "концом месяца".
    1. Добавьте день к дате и посмотрите, изменится ли номер месяца.
  2. Добавить месяц
  3. Если старая дата была "конец месяца"
    1. Установите день месяца на 1
    2. Добавить еще месяц
    3. Вычесть один день
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...