Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
New WEEKDAYS function.
Message
De
20/08/2003 13:32:47
Mike Yearwood
Toronto, Ontario, Canada
 
 
À
Tous
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Titre:
New WEEKDAYS function.
Divers
Thread ID:
00821896
Message ID:
00821896
Vues:
68
Hi!

I know this topic has come up a few times before, but here's another go at it.

First, let's agree on some terminology. According to The American Heritage Dictionary of the English Language, Fourth Edition a weekday is

adjective : occurring every day of the week except Sunday (and sometimes Saturday); "a weekday commute"; "a weekday newspaper"

noun : any day except Sunday (and sometimes except Saturday)

Let's agree to exclude vacations, holidays, employee shifts and Saturdays. These should be handled in different function(s), that may call this weekday function.

I'm only interested in *computing* weekdays (MONDAY to FRIDAY) between two dates. The routine must *NOT* count the days. IMO, it should not need to do any looping at all. The routine should stick to the simplest operations, avoiding more complex functions like MOD(), and should not call any functions more often than necessary. It should use variable names that are somewhat legible. It should be as few lines as reasonably possible. For example, it only takes 2 lines to use MIN and MAX in case the date parameters were passed backwards. It would take 5 lines to invert the dates using a temporary variable and an IF statement.

I tested it against a program that actually counted the weekdays between the passed dates, both returned the same results. I ran both routines for 100K iterations passing random dates from as much as 50K days in the past and up to 50K days in the future.

The counting routine took 6.58 HOURS to run. The weekday routine took 7 seconds.

Here's how it works. It adjusts the passed dates to make full 7 day weeks (Sunday to Saturday). This is done by moving the To date to the *NEXT* Saturday UNLESS it is a Sunday. In that case, the To date is moved back to the previous Saturday. The From date is moved to the following Saturday, unless it is already a Saturday.

The function uses only addition and subtraction operations. There is only one exception: the difference between the adjusted dates is multipled by 5/7ths. Naturally this must always be a multiple of 5 with no remainders. This eliminates any need to use MOD() to determine partial weeks. It then removes any *weekdays* introduced during the initial adjustments.

I'm interested in any comments that would improve the routine.

Here's WEEKDAYS.PRG...
LPARAMETERS tdFrom, tdTo
IF VARTYPE(m.tdFrom)#"D" OR VARTYPE(m.tdTo)#"D"
  RETURN .F.
ENDIF
LOCAL ldFrom, ldTo, lnDOWFrom, lnDOWTo
ldFrom = MIN(m.tdFrom,m.tdTo)
ldTo = MAX(m.tdFrom,m.tdTo)
lnDOWFrom = DOW(m.ldFrom,1)
lnDOWTo = DOW(m.ldTo,1)
RETURN INT(((m.ldTo + IIF(m.lnDOWTo >= 2,7 - m.lnDOWTo,-1));
  - (m.ldFrom - IIF(m.lnDOWFrom <= 6,m.lnDOWFrom - 1,0)) + 1) * 5 / 7) ;
  - IIF(m.lnDOWFrom >= 2 AND m.lnDOWFrom <= 6,m.lnDOWFrom - 2,0) ;
  - IIF(m.lnDOWTo >= 2 AND m.lnDOWTo <= 6,6 - m.lnDOWTo,0)
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform