Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
New WEEKDAYS function.
Message
From
21/08/2003 07:36:34
Walter Meester
HoogkarspelNetherlands
 
 
To
20/08/2003 13:32:47
Mike Yearwood
Toronto, Ontario, Canada
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00821896
Message ID:
00822122
Views:
36
Hi Mike,

New version.
LPARAMETERS dDate1, dDate2
LOCAL nDays

nDays = ABS(dDate1-dDate2)+1

RETURN nDays - INT(nDays/7)*2 - ;
	IIF(DOW(MIN(dDate1,dDate2),2)= 7, SIGN(nDays % 7), SIGN(DOW(MIN(dDate1,dDate2),2)-7 + (nDays % 7))+1)
In VFP8 you can take advantage of the EVL() function and do a:
LPARAMETERS dDate1, dDate2
LOCAL nDays

nDays = ABS(dDate1-dDate2)+1

RETURN nDays - INT(nDays/7)*2 - SIGN(EVL(DOW(MIN(dDate1,dDate2),2)-7,-1) + (nDays % 7)) -1
Walter,








>
>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)
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform