Add business days to a Date

By Luke Smith on November 18, 2008 8:11 PM

This morning in ##javascript, a visitor asked how to add n business days to a Date instance. Call me a sucker, but I love little tasks like this. Maybe I just get antsy when I smell a potential modulo.

I thought I would be able to find such a function pretty quickly online, but I wanted to write it first, then validate my approach against what I found. Here's what I came up with:

function addBusinessDays(d,n) {
    d = new Date(d.getTime());

    var day = d.getDay();

    d.setDate(
        d.getDate() + n +
        (day === 6 ? 2 : +!day) +
        (Math.floor((n - 1 + (day % 6 || 1)) / 5) * 2));

    return d;
}

Not terribly readable, but it works. You could omit the first line if you have no desire to preserve the input Date object. And it is hard coded to assume "business days" are between Monday and Friday. If you wanted to offset the resulting date for holidays, you could maintain an object literal keyed by a serialization of holiday dates, and in the function check against the object, rerunning the algo with n + 1 if a match was found.

Compare and contrast

It turned out after finishing the code, I had little luck finding a comparable function in the wild. Perhaps my search criteria were awful or there's not actually a market for such a function, but my findings were sparse. The closest thing I found was this gargantuan monster. I was surprised that such a function didn't show up in the DateJS lib. Regardless, both collections of functions modify the Date.prototype which I don't do.

So either I need to hone my search skills, or my efforts may have actually been worthwhile.

Here's the function minified…you know, in case you wanted to save 25b over the wire or something:

function addBusinessDays(B,C){B=new Date(B.getTime());var A=B.getDay();B.setDate(B.getDate()+C+(A===6?2:+!A)+(Math.floor((C-1+(A%6||1))/5)*2));return B;}

And a demo page showing a variety of dates and a delta range of -10 to +10.

Update 10/14/2009

I've moved this to a GitHub project and included a couple new versions. One to modify the Date in place and two others that adjust for holidays (some assembly required).

Your comment?

HTML is ok

No TrackBacks (http://lucassmith.name/mt/mt-tb.cgi/116)

ls.n

LucasSmith.name

Luke and Liam

I'm Luke. I am a front end engineer at Yahoo! on the YUI team.

Mostly I write about code stuff, but occassionally I'll mix in some real life. You've been warned.

Archives

Tags

Feeds

Subscribe to feed Recent entries

Content licensed under Creative Commons

Code licensed under BSD license

©2005 - 2010 Lucas Smith

Powered by Movable Type