“半月”要加多少天?
本文关键字:多少 半月 | 更新日期: 2023-09-27 18:17:51
我有一个名为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
}
基于NumberOfPayments
, PaymentFrequency
和FirstPaymentDate
(类型为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");
}
那么,当使用semimonmonth时,我应该使用多少天/月?如果不知道每个月之间确切的天数,这有可能吗?或者这真的很简单,我刚刚用完咖啡因,我看不到森林的树木:)
对于半月制,如果你的第一次付款总是每月的第一次付款(也就是说,从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个月(分割,其余部分被丢弃)和15天的16个月。对于第三次付款,这将增加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
因为月份有不同的长度,所以不能只添加一个预定义的数字。你必须知道你要处理的是哪个月,然后从那里开始。
如果你知道一个月的1号和16号是到期日,那么最后一次付款是12月16日(假设你计算的是日历年)
半月付款的基本对是:
- 1日和16日(每月1日和16日)
- 15 and (2|3)?(每月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;