Add or subtract Business/Working DaysFunctions written for Javascript, PHP and Lasso 9 | |
I was lately looking for a working version of a function to add and/or subtract business days. The scripts and code I found via Google somehow did not produce the correct results all the time - and I do not mean the loops that simply add a day and check for weekends. Looping and adding a day each time is slow, so why slow down if you can use a formula. So I wrote my own functions, using some old code I had from back in 1989 and some new knowledge, for Javascript, PHP and Lasso 9. The three languages I now use for all my web developments.
Tweet
Javascript
function mv_addBusinessDays(p1, p2) { /* p1 = date string: 'YYYYMMDD' p2 = business days to add or subtract (-) returns date object */ aDate = new Date(p1.substr(0,4) + '-' + p1.substr(4,2) + '-' + p1.substr(6,2)); if(!isNaN(parseInt(p1)) && parseInt(p1) != 0) { numWeeks = Math.floor(Math.abs(p2) / 5); numDays = (Math.abs(p2) % 5); dayOfWeek = aDate.getDay(); // Mo = 1, Su = 0 if(dayOfWeek == 0) dayOfWeek = 7; // Su // Correct for 1st whole week // 4 days = 0 weeks + 4 days // 5 days = 0 weeks + 5 days // 6 days = 1 week + 1 day // 10 days = 1 week + 5 days // 11 days = 2 weeks + 1 day if(numDays == 0) { numDays = 5; numWeeks -= 1; } if(parseInt(p2) < 0) numDays = numDays + ((dayOfWeek - numDays) < 1 ? 2 : 0) + (dayOfWeek > 5 ? dayOfWeek - 6 : 0); else if((dayOfWeek + numDays) > 5) numDays = (numDays + 2) - (dayOfWeek > 5 ? dayOfWeek - 5 : 0); numDays = (((numWeeks * 7) + numDays) * 1000 * 60 * 60 * 24); if(parseInt(p2) < 0) aDate.setTime(aDate.getTime() - numDays); else aDate.setTime(aDate.getTime() + numDays); } return(aDate); }
PHP
<?php function mv_addBusinessDays($p1, $p2) { /* $p1 = date string: 'YYYYMMDD' $p2 = business days to add or subtract (-) returns date object */ $date = date_create_from_format('YmdHis', $p1 . '120000')); if((int) $p2 != 0) { $numWeeks = floor(abs($p2) / 5); $numDays = (int) (abs($p2) % 5); $dayOfWeek = (int) $date->format('N'); // 1 (Monday) .. 7 (Sunday) // Correct for 1st whole week // 4 days = 0 weeks + 4 days // 5 days = 0 weeks + 5 days // 6 days = 1 week + 1 day // 10 days = 1 week + 5 days // 11 days = 2 weeks + 1 day if($numDays == 0) { $numDays = 5; $numWeeks -= 1; } if((int) $p2 < 0) { $numDays = $numDays + (($dayOfWeek - $numDays) < 1 ? 2 : 0) + ($dayOfWeek > 5 ? $dayOfWeek - 6 : 0); } elseif(($dayOfWeek + $numDays) > 5) { $numDays = ($numDays + 2) - ($dayOfWeek > 5 ? $dayOfWeek - 5 : 0); } $interval = new DateInterval('P' . abs(($numWeeks * 7) + $numDays) . 'D'); if((int) $p2 < 0) return($date->sub($interval)); else return($date->add($interval)); } else return($date); } ?>
Lasso 9
[ define_tag('mv_addBusinessDays', -required='p1', -copy, -required='p2', -copy) => { /* p1 = date string: 'YYYYMMDD' p2 = business days to add or subtract (-) returns date string */ local( 'date' = date(string(#p1) + '120000'), 'numWeeks' = 0.0, 'numDays' = 0, 'dayOfWeek' = 0) if(integer(#p2) != 0) => { #numWeeks = math_floor(math_abs(#p2) / 5) #numDays = integer(math_abs(#p2) % 5) #dayOfWeek = (#date->dayofweek) - 1; // 2 (Monday) .. 1 (Sunday) if(#dayOfWeek == 0) => { #dayOfWeek = 7 } // Correct for 1st whole week // 4 days = 0 weeks + 4 days // 5 days = 0 weeks + 5 days // 6 days = 1 week + 1 day // 10 days = 1 week + 5 days // 11 days = 2 weeks + 1 day if(#numDays == 0) => { #numDays = 5; #numWeeks -= 1; } if(integer(#p2) < 0) => { #numDays = #numDays + ((#dayOfWeek - #numDays) < 1 ? 2 | 0) + (#dayOfWeek > 5 ? #dayOfWeek - 6 | 0) else((#dayOfWeek + #numDays) > 5) #numDays = (#numDays + 2) - (#dayOfWeek > 5 ? #dayOfWeek - 5 | 0) } #numDays += (#numWeeks * 7) if(integer(#p2) < 0) => { #date->subtract(-day=#numDays) else #date->add(-day=#numDays) } } return(#date); } ]
Happy coding!