Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How many days to add for "semi-monthly"

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 :)

like image 250
zam6ak Avatar asked Dec 12 '11 22:12

zam6ak


People also ask

How many days is a semi-monthly pay period?

Semimonthly pay Employers who choose this schedule can either pay their employees on the first and 15th of the month or on the 16th and last day of the month. Semimonthly pay has 24 pay periods and is most often used with salaried workers.

How do you calculate semi-monthly?

Multiply gross pay for one bi-weekly pay period by 26 to get the annual salary. Divide the annual salary by 24 to get the gross pay for one semi-monthly period.

Is semi-monthly every 15 days?

A semimonthly payroll is paid twice a month, usually on the 15th and last days of the month. If one of these pay dates falls on a weekend, the payroll is instead paid out on the preceding Friday. A biweekly payroll is paid every other week, usually on a Friday.

How do I process semi-monthly payroll?

For a semi-monthly employee, you have to divide 2,080 by 24 pay periods (twice a month). To get the salary for either of the pay groups, you need to divide the annual salary by the number of pay periods.

How does semi-monthly work in February?

With the semimonthly schedule, you receive 24 paychecks every year. Since months are not all of equal length, some paychecks will be larger or smaller than others. For example, your second paycheck in February would only cover 13 or 14 days. Most other paychecks cover a 15 or 16 day period.


1 Answers

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
like image 81
James Michael Hare Avatar answered Sep 23 '22 10:09

James Michael Hare