Optimization of date calculation code
Author Message
Optimization of date calculation code

Hi.  In a system I'm designing I have a subroutine which calculates the
expiration date of a record given a starting date and a period of time the
record should be active, not including weekends.

As a novice programmer, I suspect that my code may be sub-optimal, and I'm
hoping to receive some pointers on how to make it not only more efficient
but also simpler and easier to read.

The trick to this task is that weekends don't count, so I can't make the
expiration date = the starting date + the period (f.e. if start date ==
friday and period == 3 days, expiration date = wednesday, not monday).

I also can't just count the number of weekend days in the period and add
that to the period, since sometimes the new larger period includes more
weekend days which should have been skipped.  For example:

if    starting date == friday the 1st
and   period == 7 days
then  period = 7 days + 2 weekend days from friday to friday = 9 days
so    expiration date = sunday the 9th # WRONG

expiration date should = tuesday the 11th because saturday the 8th and
sunday the 9th shouldn't count in the period

My solution is to use an iterative loop which checks each day from
starting date to starting date+period.  If the day is a saturday or sunday
it increases period.  Since the loop doesn't end until the counter ==
period, weekend days added to the period are checked and cause period to
increase.

sub OffsetExpireDate {

# Gets passed the starting date in gmtime format and the period
# in days, returns the expiration date in gmtime format

for (\$i = 0; \$i <= \$period; ++\$i) {

if ((\$temp[6] == 0) || (\$temp[6] == 6)) { ++\$period; }
}
\$end_time = \$start_time + \$period * 86400;
\$end_time;

Quote:
}

My basic question: Is this the most efficient, simple, and/or easy-to-read
solution to this problem?  If not, what can you suggest?

Thanks for any input,

Thu, 04 Jun 1998 03:00:00 GMT
Optimization of date calculation code
: Hi.  In a system I'm designing I have a subroutine which calculates the
: expiration date of a record given a starting date and a period of time the
: record should be active, not including weekends.
:
: As a novice programmer, I suspect that my code may be sub-optimal, and I'm
: hoping to receive some pointers on how to make it not only more efficient
: but also simpler and easier to read.
:
: The trick to this task is that weekends don't count, so I can't make the
: expiration date = the starting date + the period (f.e. if start date ==
: friday and period == 3 days, expiration date = wednesday, not monday).
:
: I also can't just count the number of weekend days in the period and add
: that to the period, since sometimes the new larger period includes more
: weekend days which should have been skipped.  For example:
:
: if    starting date == friday the 1st
: and   period == 7 days
: then  period = 7 days + 2 weekend days from friday to friday = 9 days
: so    expiration date = sunday the 9th # WRONG
:
: expiration date should = tuesday the 11th because saturday the 8th and
: sunday the 9th shouldn't count in the period
:
: My solution is to use an iterative loop which checks each day from
: starting date to starting date+period.  If the day is a saturday or sunday
: it increases period.  Since the loop doesn't end until the counter ==
: period, weekend days added to the period are checked and cause period to
: increase.

Do you have to allow for national holidays? If not, then for each 5 days
expiry time you want to add one week; thereafter, if the remaining days
are the other side of a weekend you want to add two days:

sub OffsetExpireDate {

my(\$end_time, \$days, \$weeks, \$day_of_week);

(\$weeks, \$days) = (int(\$days / 5), \$days % 5);
\$day_of_week = (localtime(\$start_time))[6];  # 0 = Sunday

# note this algorithm may work unexpectedly if start_time is a weekend
# warn "Bad start time" if \$day_of_week < 1 || \$day_of_week > 5;

if (\$day_of_week + \$days > 5) {
\$days += 2;
}
\$end_time = \$start_time + (7 * \$weeks + \$days) * 86400;
\$end_time;

Quote:
}

If you need to allow for national holidays, the whole thing becomes a
lot more difficult, and I'd have to think a lot harder about it.

Hugo van der Sanden

Fri, 05 Jun 1998 03:00:00 GMT
Optimization of date calculation code
Hi Hugo,

Thanks for coming up with what looks like a much better algorithm for the
problem.  Fortunately I don't have to account for national holidays.  If I
did, it seems like my code could be made to account for them more easily,
but yours looks much more efficient.  I haven't had a chance to test it yet.

I do have one question. Is the line that reads:

(\$weeks, \$days) = (int(\$days / 5), \$days % 5);

(\$weeks, \$days) = (int(\$expiry / 5), \$expiry % 5);

The latter seems to make more sense than the former.

myk

Quote:

> Do you have to allow for national holidays? If not, then for each 5 days
> expiry time you want to add one week; thereafter, if the remaining days
> are the other side of a weekend you want to add two days:

> sub OffsetExpireDate {

>   my(\$end_time, \$days, \$weeks, \$day_of_week);

>   (\$weeks, \$days) = (int(\$days / 5), \$days % 5);
>   \$day_of_week = (localtime(\$start_time))[6];  # 0 = Sunday

> # note this algorithm may work unexpectedly if start_time is a weekend
> # warn "Bad start time" if \$day_of_week < 1 || \$day_of_week > 5;

>   if (\$day_of_week + \$days > 5) {
>     \$days += 2;
>   }
>   \$end_time = \$start_time + (7 * \$weeks + \$days) * 86400;
>   \$end_time;
> }

> If you need to allow for national holidays, the whole thing becomes a
> lot more difficult, and I'd have to think a lot harder about it.

> Hugo van der Sanden

Sat, 06 Jun 1998 03:00:00 GMT
Optimization of date calculation code
: I do have one question. Is the line that reads:
:
:    (\$weeks, \$days) = (int(\$days / 5), \$days % 5);
:
:
:    (\$weeks, \$days) = (int(\$expiry / 5), \$expiry % 5);
:
: The latter seems to make more sense than the former.
:

Yes it should be as you suggest; my apologies for the error.

Hugo

Sun, 07 Jun 1998 03:00:00 GMT

 Page 1 of 1 [ 4 post ]

Relevant Pages