6

PaymentFrequency私は、その値が年間何回の支払いが行われているかを示すという列挙型を持っています...だから私は持っています

public enum PaymentFrequency
{
    None             = 0,
    Annually         = 1,
    SemiAnnually     = 2,
    EveryFourthMonth = 3,
    Quarterly        = 4,
    BiMonthly        = 6,
    Monthly          = 12,
    EveryFourthWeek  = 13,
    SemiMonthly      = 24,
    BiWeekly         = 26,
    Weekly           = 52
}

NumberOfPaymentsPaymentFrequency、および(DateTimeOffset 型の) に基づいて、FirstPaymentDateを計算したいと思いますLastPaymentDate。しかし、SemiMonthly の場合に追加する時間単位 (日、月) の数を把握するのに問題があります...

    switch (paymentFrequency)
    {
        // add years...
        case PaymentFrequency.Annually:
            LastPaymentDate = FirstPaymentDate.AddYears(NumberOfPayments - 1); 
            break;
        // add months...
        case PaymentFrequency.SemiAnnually:
            LastPaymentDate = FirstPaymentDate.AddMonths((NumberOfPayments - 1) * 6); // 6 months
            break;
        case PaymentFrequency.EveryFourthMonth:
            LastPaymentDate = FirstPaymentDate.AddMonths((NumberOfPayments - 1) * 4); // 4 months
            break;
        case PaymentFrequency.Quarterly:
            LastPaymentDate = FirstPaymentDate.AddMonths((NumberOfPayments - 1) * 3); // 3 months
            break;
        case PaymentFrequency.BiMonthly:
            LastPaymentDate = FirstPaymentDate.AddMonths((NumberOfPayments - 1) * 2); // 2 months
            break;
        case PaymentFrequency.Monthly:
            LastPaymentDate = FirstPaymentDate.AddMonths(NumberOfPayments - 1);
            break;
        // add days...
        case PaymentFrequency.EveryFourthWeek:
            LastPaymentDate = FirstPaymentDate.AddDays((NumberOfPayments - 1) * 4 * 7); // 4 weeks (1 week = 7 days)
            break;
        case PaymentFrequency.SemiMonthly:
            // NOTE: how many days in semi month? AddMonths (0.5) does not work :)
            LastPaymentDate = FirstPaymentDate.AddMonths((NumberOfPayments - 1) * 0.5); // 2 weeks (1 week = 7 days)
            break;
        case PaymentFrequency.BiWeekly:
            LastPaymentDate = FirstPaymentDate.AddDays((NumberOfPayments - 1) * 2 * 7); // 2 weeks (1 week = 7 days)
            break;
        case PaymentFrequency.Weekly:
            LastPaymentDate = FirstPaymentDate.AddDays((NumberOfPayments - 1) * 7); // 1 week (1 week = 7 days)
            break;
        case PaymentFrequency.None:
        default:
            throw new ArgumentException("Payment frequency is not initialized to valid value!", "paymentFrequency");
    }

では、セミマンスリーを利用する場合、何日/何ヶ月使用すればよいのでしょうか? これは、その間の各月の正確な日数を知らなくても可能ですか? それとも、これは本当に単純で、カフェインを使い果たしたばかりで、木を見て森を見ているわけではありません:)

4

4 に答える 4

7

半月払いの場合、最初の支払いが常にその月の最初の支払いである場合 (つまり、コメントで説明されているように、1 日から 13 日までのいつでも、13 日以降に開始するのは問題があります)、次のようにすることができます。

 // assuming first payment will be 1st of month, add month for every 2 payments
 // num payments / 2 (int division, remainder is chucked)
 // then add 15 days if this is even payment of the month
 LastPaymentDate = FirstPaymentDate.AddMonths((NumberOfPayments - 1) / 2)
     .AddDays((NumberOfPayments % 2) == 0 ? 15 : 0);

したがって、最初の支払いの場合、これに 0 か月と 0 日が追加されるため、最初の支払い日になります。2 回目の支払いの場合、これにより 0 か月 (int 除算、残りはチャック) が追加され、その月の 16 日に 15 日が追加されます。3 回目の支払いの場合、これにより 1 か月 (1/3) が追加され、翌月の 1 日は 0 日になります。

これは、FirstPaymentDate が特定の月の 1 日になることを前提としています。16日を開始日として許可したい場合などは、おそらくここからどこへ行くべきかがわかります.

わかる?

説明のために、次のものがあったとします。

DateTime LastPaymentDate, FirstPaymentDate = new DateTime(2011, 12, 5);

for(int numOfPayments=1; numOfPayments<=24; numOfPayments++)
{
    LastPaymentDate = FirstPaymentDate.AddMonths((numOfPayments - 1) / 2)
        .AddDays((numOfPayments % 2) == 0 ? 15 : 0);

    Console.WriteLine(LastPaymentDate);
}

このループにより、次のようになります。

12/5/2011 12:00:00 AM
12/20/2011 12:00:00 AM
1/5/2012 12:00:00 AM
// etc...
10/20/2012 12:00:00 AM
11/5/2012 12:00:00 AM
11/20/2012 12:00:00 AM
于 2011-12-12T22:15:22.973 に答える
1

月の長さはさまざまであるため、事前定義された数値を追加することはできません。あなたはあなたが扱っている月を知り、そこから行く必要があります。

月の1日と16日が期日であることがわかっている場合、最後の支払いは12月16日です(暦年を計算していると仮定します)。

于 2011-12-12T22:09:17.877 に答える
1

半月払いの基本的なペアは次のとおりです。

  • 1 と 16 (月の 1 日と 16 日)
  • 15 と (2|3)? (毎月15日と末日)

のぞいて選ぶ

于 2011-12-12T22:11:23.843 に答える
0

最近同じ問題が発生しましたが、日付の入力を許可する必要がありました。少しごちゃごちゃしていて、リファクタリングする必要がありますが、これが私が今のところ思いついたものです。2 月にはハッキングしなければならない問題がいくつかありました。

Date returnDate;

if (numberOfPayments % 2 == 0)
{
   returnDate = date.AddMonths(numberOfPayments / 2);

    if (date.Day == DateTime.DaysInMonth(date.Year, date.Month))//Last day of the month adjustment
    {
        returnDate = new Date(returnDate.Year, returnDate.Month, DateTime.DaysInMonth(returnDate.Year, returnDate.Month));
    }
}
else
{
    returnDate = date.Day <= 15 ? date.AddDays(15).AddMonths((numberOfPayments - 1) / 2) : date.AddDays(-15).AddMonths((numberOfPayments + 1) / 2);
    if (date.Day == DateTime.DaysInMonth(date.Year, date.Month))//Last day of the month adjustment
    {
        returnDate = new Date(returnDate.Year, returnDate.Month, 15);
    }
    else if (date.Month == 2 && date.Day == 14)
    {
        returnDate = returnDate.AddMonths(-1);
        returnDate = new Date(returnDate.Year, returnDate.Month, returnDate.Month == 2 ? 28 : 29);
    }
    else if (date.Month == 2 && date.Day == 15)
    {
        returnDate = returnDate.AddMonths(-1);
        returnDate = new Date(returnDate.Year, returnDateMonth, DateTime.DaysInMonth(returnDate.Year, returnDate.Month));
    }
}

return returnDate;
于 2017-03-22T18:22:49.013 に答える