“半月”加多少天

发布于 2024-12-21 00:09:15 字数 2711 浏览 3 评论 0原文

我有一个名为 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
}

根据 NumberOfPaymentsPaymentFrequencyFirstPaymentDate(DateTimeOffset 类型)计算 LastPaymentDate。但我在计算半月一次的情况下要添加多少个时间单位(天、月)时遇到问题...

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

那么,使用半月时我应该使用多少天/月? 如果不知道中间每个月的确切天数,这是否可能? 或者这真的很简单吗?我刚刚喝完咖啡因,只见树木不见森林:)

I have a enum type called PaymentFrequency whose values indicate how many payments per year are being made...
So I have

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
}

Based on NumberOfPayments, PaymentFrequency, and FirstPaymentDate (of type DateTimeOffset) I want to calculate LastPaymentDate. But I am having issue figuring out how many time units (days, months) to add in case of 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");
    }

So, how many days/months should I use when using SemiMonthly?
Is this even possible without knowing exact # of days for each month in between?
Or is this really simple, and I have just run out of caffeine and I am not seeing forest for the trees :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

她说她爱他 2024-12-28 00:09:15

对于半月付款,如果您的第一笔付款也始终是该月的第一笔付款(即从 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 天,因此是第一次付款日期。对于第二次付款,这将增加 0 个月(整除,余数被丢弃)和 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

For Semi-Monthly, if your first payment was always the 1st payment of the month as well (that is, anytime from the 1st to the 13th, starting after 13th is problematic as discussed in the comments), you could do as follows:

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

So for the 1st payment, this will add 0 months and 0 days so be 1st payment date. For 2nd payment, this will add 0 months (int dividision, remainder is chucked) and 15 days for 16th of month. For 3rd payment, this will add 1 month (1 / 3) and 0 days for 1st of next month, etc.

This is assuming that the FirstPaymentDate will be on the 1st of some given month. You can probably see where to go from here if you want to allow the 16th to be a starting date, etc.

Make sense?

So to illustrate, if we had:

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

This loop would give us:

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
小ぇ时光︴ 2024-12-28 00:09:15

由于月份的长度各不相同,因此您不能只添加预定义的数字。您必须知道您正在处理哪个月份,然后从那里开始。

如果您知道每月 1 日和 16 日是到期日,那么最后一次付款是 12 月 16 日(假设您计算的是日历年)。

Because months have varying lengths, you can't just add a pre-defined number. You have to know which month you are dealing with, and go from there.

If you know that the 1st and the 16th of a month are due dates, then the last payment is December 16th (assuming you are calculating for a calendar year).

<逆流佳人身旁 2024-12-28 00:09:15

半月付款的基本对是:

  • 1 和 16(每月的 1 号和 16 日)
  • 15 和(2|3)? (每月15日和最后一天)

查看并选择

The basic pairs for semi monthly payments are:

  • 1 and 16 (the 1st and 16th day of a month)
  • 15 and (2|3)? (the 15th and the last day of the month)

Peek and choose

苍暮颜 2024-12-28 00:09:15

我最近遇到了同样的问题,但我需要允许任何日期输入。这有点混乱,需要重构,但这就是我到目前为止想到的。二月遇到了一些我必须解决的问题。

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;

I've recently had the same issue, but I needed to allow any date input. It's a bit of a mess and needs to be refactored, but this is what I came up with so far. February had some problems that I had to hack.

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文