为"半月刊"添加多少天

zam*_*6ak 6 c# datetime date datetimeoffset

我有一个名为enum的类型,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
}
Run Code Online (Sandbox Code Playgroud)

基于NumberOfPayments,PaymentFrequency和,FirstPaymentDate(类型的DateTimeOffset)我想计算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");
    }
Run Code Online (Sandbox Code Playgroud)

那么,使用SemiMonthly时我应该使用多少天/月?如果不知道每个月的确切天数,这是否可能?或者这真的很简单,我刚用完了咖啡因而且我没有看到森林里的树木:)

Jam*_*are 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);
Run Code Online (Sandbox Code Playgroud)

因此,对于第一次付款,这将添加0个月和0天,因此是第一个付款日期.对于第二次付款,这将增加0个月(int dividision,其余被清除)和15个月的16个月.对于第三次付款,这将增加1个月(1/3)和下个月1日的0天等.

这假设FirstPaymentDate将在某个月的第一天.如果你想让第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);
}
Run Code Online (Sandbox Code Playgroud)

这个循环会给我们:

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
Run Code Online (Sandbox Code Playgroud)