Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Number of Mondays in a month
Message
From
20/10/2016 07:27:39
 
 
To
19/10/2016 23:45:34
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
01642129
Message ID:
01642140
Views:
75
>>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  && Test0
>
>*-------------------------------------------------------------------------------
>
>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  && Test1
>
>*-------------------------------------------------------------------------------
>
>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  && Test2
>
>*-------------------------------------------------------------------------------
>
>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  && BF_BegDowMonth
>
>*-------------------------------------------------------------------------------
>
>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  && BF_DowCnt
>
>*-------------------------------------------------------------------------------
>
>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  && DowCnt1
>
>*-------------------------------------------------------------------------------
>
>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  && BegDowMonth
>
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.
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform