>>The application has to determine how many occurrences of a given day of the week occurred in a given calendar month.
>>
>>For example- How many Mondays (or any other specified day of the week) were there in February, 2016?
>>I can see how to get the answer by looping through all the days in the month in question, but is there a slicker way?
>
>Something I slapped together... There is likely an easier way than I've got here (e.g. something like how Zeller's Congruence can be used to compute day of week).
>
>main point of interest is function DowCnt1().
>
>
LOCAL bPass
>
>bPass = .T.
>DO Test0 WITH m.bPass
>
>IF m.bPass THEN
> DO Test1 WITH m.bPass
>ENDIF
>
>IF m.bPass THEN
> DO Test2 WITH m.bPass
>ENDIF
>
>RETURN
>
>*-------------------------------------------------------------------------------
>
>PROCEDURE Test0( bPass )
> LOCAL nDOW,nYr,nMo, bOK, nFail, ;
> dRef,dF0
>
> nFail = 0
> FOR nDOW = 1 TO 7
> FOR nYr = 1900 TO 2100
> FOR nMo = 1 TO 12
> bOK = .T.
>
> * Test "brute-force" fisrt day month with given DOW
> dRef = DATE(m.nYr,m.nMo,1)
> dF0 = BF_BegDowMonth(m.nYr,m.nMo,m.nDOW)
> bFail = .F.
> IF MONTH(m.dF0)<>MONTH(m.dRef) OR YEAR(m.dF0)<>YEAR(m.dRef) THEN
> bFail = .T.
> ELSE
> IF DOW(m.dF0)<>m.nDOW THEN
> bFail = .T.
> ELSE
> IF (m.dF0 - m.dRef) >= 7 THEN
> bFail = .T.
> ENDIF
> ENDIF
> ENDIF
> IF m.bFail THEN
> nFail = m.nFail + 1
> ? m.nDOW, m.nYr, m.nMo
> ENDIF
>
> ENDFOR
> ENDFOR
> ENDFOR
> ? "Test 0:", IIF(m.nFail==0,"PASS","FAIL")
>ENDPROC
>
>*-------------------------------------------------------------------------------
>
>PROCEDURE Test1( bPass )
> LOCAL nDOW,nYr,nMo, bOK, nFail, ;
> dRef,dF0
>
> nFail = 0
> FOR nDOW = 1 TO 7
> FOR nYr = 1900 TO 2100
> FOR nMo = 1 TO 12
> bOK = .T.
>
> * Test "brute-force" fisrt day month with given DOW
> dRef = DATE(m.nYr,m.nMo,1)
> dF0 = BegDowMonth(m.nYr,m.nMo,m.nDOW)
> bFail = .F.
> IF MONTH(m.dF0)<>MONTH(m.dRef) OR YEAR(m.dF0)<>YEAR(m.dRef) THEN
> bFail = .T.
> ELSE
> IF DOW(m.dF0)<>m.nDOW THEN
> bFail = .T.
> ELSE
> IF (m.dF0 - m.dRef) >= 7 THEN
> bFail = .T.
> ENDIF
> ENDIF
> ENDIF
> IF m.bFail THEN
> nFail = m.nFail + 1
> ? m.nDOW, m.nYr, m.nMo
> ENDIF
>
> ENDFOR
> ENDFOR
> ENDFOR
> ? "Test 1:", IIF(m.nFail==0,"PASS","FAIL")
>ENDPROC
>
>*-------------------------------------------------------------------------------
>
>PROCEDURE Test2( bPass )
> LOCAL nDOW,nYr,nMo, bOK, nFail, ;
> dRef,dF0
>
> nFail = 0
> FOR nDOW = 1 TO 7
> FOR nYr = 1900 TO 2100
> FOR nMo = 1 TO 12
> bOK = .T.
>
> nC0 = BF_DowCnt(m.nYr,m.nMo,m.nDOW)
> nC1 = DowCnt1(m.nYr,m.nMo,m.nDOW)
> bFail = .F.
> IF m.nC0 <> m.nC1 THEN
> bFail = .T.
> ENDIF
> IF m.bFail THEN
> nFail = m.nFail + 1
> ? m.nDOW, m.nYr, m.nMo, nC0,m.nC1
> ENDIF
> ENDFOR
> ENDFOR
> ENDFOR
> ? "Test 2:", IIF(m.nFail==0,"PASS","FAIL")
>ENDPROC
>
>*-------------------------------------------------------------------------------
>
>FUNCTION BF_BegDowMonth(nYr,nMo,nDOW)
> * A "brute-forcce" method of getting first day of a month that has a gven
> * day of week.
> LOCAL dDt,dRet,I
>
> dRet = {}
> dDt = DATE(m.nYr,m.nMo,1)
> FOR I=1 TO 8
> IF DOW(m.dDt)==m.nDOW THEN
> dRet = m.dDt
> EXIT
> ENDIF
> dDt = m.dDt + 1
> ENDFOR
> RETURN m.dRet
>ENDFUNC
>
>*-------------------------------------------------------------------------------
>
>FUNCTION BF_DowCnt(nYr,nMo,nDOW)
> * "Brute-force" method of counting days in a month that match a given
> * day of week.
> LOCAL dDt,nCnt
>
> nCnt = 0
> dDt = DATE(m.nYr,m.nMo,1)
> DO WHILE MONTH(m.dDt)==m.nMo AND YEAR(m.dDt)==m.nYr
> IF DOW(m.dDt)==m.nDOW THEN
> nCnt = m.nCnt + 1
> ENDIF
> dDt = m.dDt + 1
> ENDDO
> RETURN m.nCnt
>ENDFUNC
>
>*-------------------------------------------------------------------------------
>
>FUNCTION DowCnt1(nYr,nMo,nDOW)
> * A slightly more involved method (which should be a tad faster than the
> * "brute force" method of counting days in a month that match a given
> * day of week.
> LOCAL d0,d1, dN
>
> d0 = BegDoWMonth(m.nYr,m.nMo,m.nDOW)
> dN = GOMONTH(DATE(m.nYr,m.nMo,1),1)
> d1 = BegDoWMonth(YEAR(m.dN),MONTH(m.dN),m.nDOW)
> RETURN INT( ( m.d1 - m.d0 ) / 7)
>ENDFUNC
>
>*-------------------------------------------------------------------------------
>
>FUNCTION BegDowMonth(nYr,nMo,nDOW)
> * A slightly more involved method of getting the first day of a month that
> * has a gven day of week.
> LOCAL dDt,dRet
>
> dDt = DATE(m.nYr,m.nMo,1)
> dRet = m.dDt - DOW(m.dDt) + m.nDOW
> IF MONTH(m.dRet) <> m.nMo THEN
> dRet = m.dRet + 7
> ENDIF
> RETURN m.dRet
>ENDFUNC
>
Thank you, Naoto.
As you said, some of the other suggestions seem simpler.
I'll try them and then look at this one.
Anyone who does not go overboard- deserves to.
Malcolm Forbes, Sr.