From: g9utxu@fnma.COM (Tanin Uthayanaka)
Subject: Re: Pls help: algorithm wanted (xbase, pref foxpro)
Reply-To: g9utxu@fnma.COM
Organization: Fannie Mae
Date: Mon, 4 Jan 1993 20:13:19 GMT

In article 28479@pegasus.com, tleylan@pegasus.com (Tom Leylan) writes:
>durai@ortta.umn.edu (Durai Venkatasubramanian) writes:
>
>>I need an algorithm to accomplish a date comparison task.  Any help will be 
>>appreciated and gratefully remembered for life.
>
>The following will do what you want.  I started with the other poster's
>code and "structured" it (a little better (in my opinion)) and as you
>will notice the code resides in a function which is called repeatedly
>until the function sends back a signal saying it is done.
>
>It is in Clipper 5.0 but I don't think there is anything that won't
>translate into FoxPro.  I left some of the Clipper-only initializations
>and stuff out to facilitate it.
>
>I wrote another version which adds a little more complexity but also
>adds flexibility in that the PrintRate() function didn't actually print
>the results but rather returned them to Main() which could then print
>the BegDate, EndDate and Status or do whatever else it might want to
>like write it to a file, send it through a fax card or whatever.
>
>Oh... you should add append one extra record to your database which is
>a dummy that covers all dates from the last "real" one to the end of
>time or 01/01/95 - 12/31/99 in your sample and figuring that the end
>of time is the end of this century.  By adding the record some code is
>eliminated which has to check if the EOF() condition was a false hit
>on the last record.  Personally I'd make the status "unknown" rather
>than "uncovered" on that dummy record because it indicates you shot
>past the scope of the system.  The person would be uncovered but it
>might serve as a warning that you typed a date in wrong or something.
>
>No big deal and you know what you're doing better than I do.
>
>Oh... the first line is just a Clipper header file which I reference
>in PrintRate() to SET SOFTSEEK on and off again without having to know
>what the status is in the rest of the application.
>
>tom
>
>
>#include "set.ch"
>
>FIELD START_DATE, END_DATE, STATUS
>
>MEMVAR getlist
>
>FUNCTION Main
>   LOCAL dBeg, dEnd
>   LOCAL aDates[ 2 ]
>
>   USE RATE EXCLUSIVE NEW ALIAS Rate
>   INDEX ON Rate->START_DATE TO START
>
>   CLS
>
>   aDates[ 1 ] := CTOD( "" )
>   aDates[ 2 ] := CTOD( "" )
>
>   @ 0, 0 SAY "Beg Date : " GET aDates[ 1 ] PICT "@D"
>   @ 2, 0 SAY "End Date : " GET aDates[ 2 ] PICT "@D"
>   READ
>
>   ?
>   ? "Subcontract Period: " +;
>      DTOC( aDates[ 1 ] ) + " - " + DTOC( aDates[ 2 ] )
>   ?
>
>   WHILE PrintRate( aDates )
>   ENDDO
>
>   CLOSE Rate
>
>   RETURN NIL
>
>
>FUNCTION PrintRate( aDates )
>   LOCAL lRet := .F.
>
>   LOCAL xSoft := SET( _SET_SOFTSEEK, .T. )
>
>   SEEK aDates[ 1 ]
>
>   IF ( Rate->( EOF() ) )
>      OutStat( aDates[ 1 ], aDates[ 2 ], "Uncovered" )
>
>   ELSE
>
>      IF ! ( aDates[ 1 ] == Rate->START_DATE )
>         SKIP -1
>      ENDIF
>
>      IF ( aDates[ 2 ] <= Rate->END_DATE )
>         OutStat( aDates[ 1 ], aDates[ 2 ], Rate->STATUS )
>
>      ELSE
>         OutStat( aDates[ 1 ], Rate->END_DATE, Rate->STATUS )
>         aDates[ 1 ] := ( Rate->END_DATE + 1 )
>         lRet := .T.
>
>      ENDIF
>
>   ENDIF
>
>   SET( _SET_SOFTSEEK, xSoft )
>
>   RETURN lRet
>
>
>FUNCTION OutStat( dBeg, dEnd, cMsg )
>   ? DTOC( dBeg ) + " - " + DTOC( dEnd ) + " = " + cMsg
>
>   RETURN NIL
>


I like this program, it is efficient and structured. But does it work...I tried using 
the following:

RATE.DBF    Record   START_DATE    END_DATE   STATUS
               1      07/01/91     06/30/92   FINAL
               2      07/01/92     06/30/93   FINAL
               3      07/01/93     12/31/93   PROVL
               4      01/01/94     06/30/94   FINAL


dBeg = 07/01/90
dEnd = 07/01/95

RESULTS:  Subcontract: 07/01/90 - 07/01/95

          07/01/90 - 06/30/92 = FINAL
          07/01/92 - 06/30/93 = FINAL
          07/01/93 - 12/31/93 = PROVL
          01/01/94 - 06/30/94 = FINAL
          07/01/94 - 07/01/95 = UNCOVERED


Also, try the following:

RATE.DBF    Record   START_DATE    END_DATE   STATUS
               1      07/01/91     06/30/92   FINAL

dBeg = 01/01/92
dEnd = 01/01/93


I beleive I made the same mistake on my first version, then I corrected it on my 
second version with one bug which no one has found yet.