Montag, 7. Mai 2012

Datumsspielereien (Teil 9) / Date gadgets (Part 9)

Irgendwie sind Datumberechnungen ein Faß ohne Boden. Nach Teil 4 der Datumsspielereien war ich bereits der Meinung, nichts neues mehr zu diesem Thema zu finden. Aber irgendwie poppt in unregelmäßigen Abständen immer wieder eine neue Frage dazu auf.

Aktuell dreht es sich darum herauszufinden, wieviele Jahre, Monate und Tage zwischen zwei Datumswerten liegen.

Im folgenden Mustercode erledigt diese Aufgabe eine kleine Schleife die zunächst die Jahre, danach die Monate und letztendlich die Tage aufaddiert und uns so den genauen Zeitraum übermittelt.

Somehow, date calculations are a bottomless pit. With Part 4 of my date gadgets I was sure to find nothing new on this subject. But somehow every now and then, a new question pops up.

This post is about finding out the period between two dates.

The following sample code does this by using a loop that first adds years, then months and finally the days to give us the exact time between the given date values.


LOCAL ldDate1 AS Date, ldDate2 AS Date, liYear AS Integer, liMonth AS Integer, liDay AS Integer, llStatus as Boolean
ldDate1 = {28.8.1961}
ldDate2 = DATE()
STORE 0 TO liYear, liMonth, liDay

llStatus = GetPeriodBetweenDates( ldDate1 , ldDate2 , @liYear , @liMonth , @liDay )

CLEAR 
IF llStatus = .T.
    ? [Zeitraum zwischen ] + DTOC( ldDate1 ) + [ und ] + DTOC( ldDate2 )
    ?  TRANSFORM( liYear )  + [ Jahr]  + IIF( liYear  <> 1 , [e ] , [ ] )
    ?? TRANSFORM( liMonth ) + [ Monat] + IIF( liMonth <> 1 , [e ] , [ ] )
    ?? TRANSFORM( liDay )   + [ Tag]   + IIF( liDay   <> 1 , [e ] , [ ] )
ENDIF 

FUNCTION GetPeriodBetweenDates as Boolean

    * // Parameter 3-5 als Referenz übergeben!
    * // Parameters 3-5 by reference
    LPARAMETERS vDate1 as Date, vDate2 as Date, vYear as Integer, vMonth as Integer, vDay as Integer

    LOCAL ldDate1 as Date, ldDate2 as Date
    ldDate1 = IIF( vDate1 > vDate2 , vDate2 , vDate1 )
    ldDate2 = IIF( vDate1 > vDate2 , vDate1 , vDate2 )

    STORE 0 TO vYear , vMonth , vDay

    DO WHILE ldDate1 < ldDate2
        DO CASE 
        CASE GOMONTH( ldDate1 , 12 ) < ldDate2
            vYear = vYear + 1 
            ldDate1 = GOMONTH( ldDate1 , 12 )
        CASE GOMONTH( ldDate1 , 1 ) < ldDate2
            vMonth = vMonth + 1 
            ldDate1 = GOMONTH( ldDate1 , 1 )
        OTHERWISE 
            vDay = vDay + 1 
            ldDate1 = ldDate1 + 1 
        ENDCASE 
    ENDDO 

    RETURN .T.

ENDFUNC