one_day); $pay_date_iteration = 0; // start with our first available pay date (first iteration of all upcoming pay dates) // loop until we have satisfied our 10 day minimum while ($due_date < $minimum_payday) { $due_date = $this->nextPayday($fund_day, $pay_span, $pay_day,$pay_date_iteration); if(!$direct_deposit) { $due_date += $this->one_day; } // process all weekends and holidays, return due_date that does not fall on any of these $due_date = $this->processNonPaydays($due_date, $holiday_array); // while due_date not valid ( > minimum_payday ), try next pay_date iteration $pay_date_iteration += 1; } // Final Due Date = 1st $pay_day after $fund_day return $due_date; } /** * Calculate next possible payday after the fund_day according to our pay_span * * @param unix_timestamp $fund_day The day the loan was funded * @param string $pay_span A string representing the frequency at which the customer is paid. (weekly,bi-weekly,monthly) * @param unix_timestamp $pay_day A timestamp containing one of the customers paydays * @param int $pay_date_iteration Number of pay dates to skip * @param unix_timestamp $pay_day A timestamp containing one of the customers paydays * * Assumptions: * Monthly paydays are on a fixed date (1st, 30th, etc). * Weekly days are fixed to days of the week (monday, tues; every 7 days) * Bi-weekly is are fixed to days of the week (every 2 weeks; 14 days) * */ private function nextPayday($fund_day, $pay_span, $pay_day, $pay_date_iteration) { // middle of a payperiod (first pay date iteration) if($pay_day > $fund_day && $pay_date_iteration == 0) { $pay_frequency = 0; } // all paychecks after the first payperiod else { switch ($pay_span) { case "weekly": $pay_frequency = 7; break; case "bi-weekly": $pay_frequency = 14; break; case "monthly": $pay_frequency = date('t', $fund_day); // # of days in funding month break; default: $pay_frequency = 30; break; } } $pay_frequency *= $pay_date_iteration; // jump to x iteration of pay dates $int_fund_day = date("j",$fund_day); // int representing day of month for fund_day $int_pay_day = date("j",$pay_day); // int representing day of month for pay_day $offset = $int_fund_day - $int_pay_day; // difference between fund_day and pay_day $remaining_days = $pay_frequency - $offset; // days left til payday // next pay day is fund_day + days til payday $next_pay_day = $fund_day + ($remaining_days*$this->one_day); return $next_pay_day; } /** * Process weekends and holiday * * @param unix_timestamp $due_date * @param array $holiday_array An array of unix timestamp's containing holidays. */ private function processNonPaydays($due_date, $holiday_array) { // check for holiday if($this->isHoliday($due_date, $holiday_array)) { // special case (if holiday is Monday, shift payday to previous Friday; minus 3 days) if(date("N",$due_date) == 1) { $due_date -= (3*$this->one_day); } // all other holiday days, shift payday back by one day else { $due_date -= $this->one_day; } // reprocess with adjusted due_date return $this->processNonPaydays($due_date, $holiday_array); } else { // if weekend day, add one day, reprocess with adjusted due_date if($this->isWeekend($due_date)) { $due_date += $this->one_day; return $this->processNonPaydays($due_date, $holiday_array); } else { return $due_date; } } } /** * Checks due_date for possibility of being a weekend day * * @param unix_timestamp $due_date Day to check for weekend * @return bool true/false based on whether $due_date is a weekend day */ private function isWeekend($due_date) { // If $due_date is a Sat or Sun, true if (date("N",$due_date) == 6 || date("N",$due_date) == 7) return true; else return false; } /** * Checks due_date against holiday_array for possibility of falling on a holiday * * @param unix_timestamp $due_date * @return bool true/false based on whether $due_date is a holiday */ private function isHoliday($due_date, $holiday_array) { return in_array($due_date, $holiday_array); } } /** * Holidays * -Federal holidays courtesy of http://www.opm.gov/Operating_Status_Schedules/fedhol/2009.asp * -Timestamps courtesy of http://www.unixtimestamp.com * * Holiday Timestamp * January 1st, 2009 | 1230832800 * MLK January 19, 2009 | 1232388000 * Presidents Day Feb 16, 2009 | 1234807200 * Memorial Day May 25, 2009 | 1243270800 * July 4, 2009 | 1246726800 * Labor Day September 7, 2009 | 1252342800 * Columbus Day Oct 12, 2009 | 1255366800 * Veterans Day Nov 11, 2009 | 1257962400 * Thanksgiving Nov 26, 2009 | 1259258400 * Christmas Dec 25, 2009 | 1261764000 * * All timestamps are as 12:00. ex. TIME STAMP: 1261764000 DATE: 12 / 25 / 2009 @ 12:00 */ $holiday_array = array(1230832800, 1232388000, 1234807200, 1243270800, 1246726800, 1252342800, 1255366800, 1257962400, 1259258400, 1261764000); $Paydate_Calculator = new Paydate_Calculator(); ?>