2013-11-01 5 views
-3

Предположим, что Банк-Клиент оплачивает взлеты RD в каждый последний день месяца.Как узнать количество платежей между двумя датами?

Так должно быть 2 рассрочка между датами 12 октября 2013 и 10 декабря 2013 г.

Как я могу узнать, сколько рассрочка клиент заплатил за этот период зубца?

Должен ли я использовать NodaTime library?

Хорошо. Вот мои усилия:

public sealed class DateDifference 
{ 
    int years; 

    public int Years 
    { 
     get { return years; } 
    } 
    int months; 

    public int Months 
    { 
     get { return months; } 
    } 
    int days; 

    public int Days 
    { 
     get { return days; } 
    } 

    public override string ToString() 
    { 
     return string.Format("[DateDifference Years={0}, Months={1}, Days={2}]", years, months, days); 
    } 


    public DateDifference(DateTime earlier, DateTime later) 
    { 
     if (later < earlier) 
      throw new ArgumentException("later is earlier than 'earlier'."); 
     bool isleapday = (earlier.Month == 2 && earlier.Day == 29); 
     DateTime tmp = isleapday ? new DateTime(earlier.Year, 2, 28) : earlier; 
     while (true) 
     { 
      try 
      { 
       tmp = tmp.AddYears(1); 
       if (isleapday && DateTime.IsLeapYear(tmp.Year)) 
        tmp = new DateTime(tmp.Year, 2, 29); 
      } 
      catch (ArgumentOutOfRangeException) 
      { 
       break; 
      } 
      if (tmp <= later) 
      { 
       years++; 
       earlier = tmp; 
      } 
      else 
      { 
       break; 
      } 
     } 
     // Add months 
     tmp = earlier; 
     while (true) 
     { 
      try 
      { 
       tmp = tmp.AddMonths(1); 
       if (isleapday && tmp.Day != 29 && tmp.Month != 2) 
        tmp = new DateTime(tmp.Year, tmp.Month, 29); 
      } 
      catch (ArgumentOutOfRangeException) 
      { 
       break; 
      } 
      if (tmp <= later) 
      { 
       months++; 
       earlier = tmp; 
      } 
      else 
      { 
       break; 
      } 
     } 
     tmp = earlier; 
     while (true) 
     { 
      try 
      { 
       tmp = tmp.AddDays(1); 
      } 
      catch (ArgumentOutOfRangeException) 
      { 
       break; 
      } 
      if (tmp <= later) 
      { 
       days++; 
       earlier = tmp; 
      } 
      else 
      { 
       break; 
      } 
     } 
    } 

DateDifference dateDifference = new DateDifference(startDateTextBox.Value, endDateTextBox.Value); 

      this.noOfInstallmentsTextBox.Text = ((int)++dateDifference.Months).ToString(); 
+0

Вы должны, вероятно, показать некоторые усилия, в первую очередь. Получите платежи, которые заплатил клиент, ограничьте их до рассрочки между этими двумя датами и получите свойство «Count». –

+0

@BROY: сначала Пожалуйста, покажите нам, что вы сделали. так что мы можем вам помочь. –

ответ

1

Я надеюсь, что это вам поможет.

int foo(DateTime start, DateTime end) 
{ 
    int count = end.Month - start.Month; 
    if (count < 0) 
     count += 12; 
    count += 12 * (end.Year - start.Year); 
    return count; 
} 
+0

Нужна специальная проверка, чтобы увидеть, является ли «конец» последним днем ​​месяца (тогда будет +1, если OP хочет его включительно) –

+1

Что делать, если 'start' и' end' не установлены в один и тот же часовой пояс или тот же календарь? – Servy

+0

daniel, я не уверен, что фиксирует нюанс последнего дня месяца, измеряя даты. этот код даст две партии, если дата начала была 01 января 2013 года, а дата окончания была 01-фев-2013 –

1

Итак, я начну с того, что говорю, что я не приоритет скорости здесь. Проблемы с Datetime сложны. Написание методов, которые вы можете быть уверены, будет работать во всех видах угловых дел по всему миру: hard. Этот подход разработан, чтобы работать, несмотря на все краевые случаи, и для этого ясность читателю. Он не пытается сделать оптимизацию кливера, потому что они не работают в случаях с нечетным краем, которые просто слишком часто игнорируются в мире datetime.

Так первый прочь, мы начнем с простым вспомогательным методом, чтобы получить все дни между двумя датами:

public static IEnumerable<DateTime> Days(DateTime start, DateTime end) 
{ 
    DateTime current = start; 
    while (current < end) 
    { 
     yield return current; 
     current = current.AddDays(1); 
    } 
} 

(Если вы хотите что-то более общее назначение здесь вы можете получить следующую дату после start , если вы хотите, чтобы все возвращаемые значения были «полуночими». Вы также можете обменять start и end, если они находятся в обратном порядке или выбрасывают исключение и т. д. Также рассмотрите точные семантики, которые вы хотите, у меня есть ограничения, включенные в пуск и эксклюзив по окончанию, вы можете захотеть его полностью включительно, полностью эксклюзивным и т. д.)

Мы также создадим способ определения, является ли дата последним днем ​​месяца.

public static bool IsLastDayOfMonth(DateTime date) 
{ 
    return date.AddDays(1).Month != date.Month; 
} 

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

Теперь, когда мы объединяем их вместе мы имеем реализацию, которая очень проста и понятна читателю:

public static int InstallmentCount(DateTime start, DateTime end) 
{ 
    return Days(start, end) 
     .Where(day => IsLastDayOfMonth(day)) 
     .Count(); 
} 
+0

Последний день месяца был аналогией. Процедура должна работать в любой день месяца. – anonymous

+0

@BROY Тогда все, что вам нужно сделать, это изменить «IsLastDayOfMonth» на любую логику, которая у вас есть, для определения того, является ли это данным днем. Если вы хотите знать, если это первый день месяца, сравните 'date.Day' с одним или 15 или каким-нибудь другим днем, в котором вы заинтересованы. – Servy

Смежные вопросы