Todd Benson
7/19/2008 6:09:00 PM
On Fri, Jul 18, 2008 at 11:20 AM, Kaldrenon <kaldrenon@gmail.com> wrote:
> Hi all,
>
> I'm doing some planning to write a simple utility program for
> maintaining my schedule. The basic scenario is that, in my job, I have
> a series of multi-stage procedures to perform, and for each instance
> of the procedure, the stages need to happen a fixed number of business
> days apart (i.e, if step one happens on Monday, step two is Friday,
> but if step one is Tuesday, step two will be the following Monday). As
> one of the first steps of the program, I'm going to write a script to
> quickly spit out the calendar dates of all steps given the date of the
> first and the relative date (in business days) of all the others.
>
> My question is, can you help me drum up a 'smart' way to take weekends
> and holidays into account? I know that with Ruby's Date class you can
> use the - (minus) operator to subtract x days from the date of an
> existing event. which is how I can find the exact date once I've
> determined the number of total days it will be before it has been x
> business days.
>
> But the "human" solution to the problem isn't very efficient -
> iterating over the days with a counter, checking Date.wday, ignoring
> days that return 0 and 6, and spitting back the date at which the
> counter reaches x. I'd like to find a more elegant and computationally
> efficient solution.
>
> If you've worked out this problem before, or a better solution seems
> readily available to you, I'd love input. If my explanation was
> unclear, I'll gladly clarify anything.
>
> -Andrew Fallows
Maybe build a calendar beforehand that only includes work days...
w_days = [nil] + (Date.today..Date.today +
some_number_of_days).map.select {|day| (day.cwday / 5).zero?}
...and then later...
w_days -= holiday_dates #which is an array of holiday Date objects chosen by you
...which afterwards you could walk through 6 at a time.
That, to me is somewhat elegant and robust, but Siep's idea will work
if the script/program will always run from a weekday. You will notice
the peculiarity that Saturday acts like Monday and Sunday acts like
Tuesday with Siep's example.
I'd probably create a WorkCalendar class, though.
Todd