| 1 | SPNLRUDT ; ISC-SF/GMB - SCD DATE UTILITIES; 6 JUL 94 [ 07/12/94  6:54 AM ] ;3/27/98  08:34
 | 
|---|
| 2 |  ;;2.0;Spinal Cord Dysfunction;**4,5**;01/02/1997
 | 
|---|
| 3 |  ; This routine contains all the date utilities.
 | 
|---|
| 4 |  ; TESTMATH     routine to test DATEMATH
 | 
|---|
| 5 |  ; DATEMATH     function to increment/decrement any FM date
 | 
|---|
| 6 |  ; DATEEOM      function to return the last date of the month
 | 
|---|
| 7 |  ; DATEFMT      function to format an FM date into a more common form
 | 
|---|
| 8 | TESTMATH ;
 | 
|---|
| 9 |  N IDATE,INCR
 | 
|---|
| 10 |  W !,"Welcome to the DATEMATH test!"
 | 
|---|
| 11 |  W !,"Date must be in FM yyymmdd format."
 | 
|---|
| 12 |  W !,"Increment must be a positive or negative number followed by D,W,M, or Y."
 | 
|---|
| 13 |  W !,"(Stands for Day, Week, Month, or Year)"
 | 
|---|
| 14 |  W !,"For example, 2940331 and 1W equals 2940407.  Now you try it...",!
 | 
|---|
| 15 |  F  D  Q:IDATE=""!(INCR="")
 | 
|---|
| 16 |  . R !,"Enter date:      ",IDATE:DTIME Q:IDATE=""
 | 
|---|
| 17 |  . R !,"Enter increment: ",INCR:DTIME Q:INCR=""
 | 
|---|
| 18 |  . W !,"Result is:       ",$$DATEMATH(IDATE,INCR),!
 | 
|---|
| 19 |  Q
 | 
|---|
| 20 | DATEMATH(IDATE,INCR) ;
 | 
|---|
| 21 |  ; DATEMATH is a function which will add (or subtract) any number of
 | 
|---|
| 22 |  ; days, weeks, months, or years to (or from) a given date.
 | 
|---|
| 23 |  ;
 | 
|---|
| 24 |  ; IDATE  The given date (FM yyymmdd format)
 | 
|---|
| 25 |  ; INCR   The increment, a positive or negative number followed by
 | 
|---|
| 26 |  ;        D (day), W (week), M (month), or Y (year).
 | 
|---|
| 27 |  ;
 | 
|---|
| 28 |  ; Examples:
 | 
|---|
| 29 |  ;
 | 
|---|
| 30 |  ; S NEXTYEAR=$$DATEMATH("2940501","1Y") ... sets NEXTYEAR to "2950501"
 | 
|---|
| 31 |  ; S YESTRDAY=$$DATEMATH("2940501","-1D")... sets YESTRDAY to "2940430"
 | 
|---|
| 32 |  ; 
 | 
|---|
| 33 |  N RESULT,LEN,TYPE,QUAN,X,X1,X2,ZDAY,MONTHS,MONTH,YEAR,YEARS
 | 
|---|
| 34 |  S LEN=$L(INCR)
 | 
|---|
| 35 |  S TYPE=$E(INCR,LEN)
 | 
|---|
| 36 |  S QUAN=$E(INCR,1,LEN-1)
 | 
|---|
| 37 |  I TYPE="W" S QUAN=QUAN*7,TYPE="D"
 | 
|---|
| 38 |  I TYPE="D" D  Q X
 | 
|---|
| 39 |  . S X1=IDATE
 | 
|---|
| 40 |  . S X2=QUAN
 | 
|---|
| 41 |  . D C^%DTC
 | 
|---|
| 42 |  I TYPE="M" D
 | 
|---|
| 43 |  . S MONTHS=$E(IDATE,4,5)+QUAN
 | 
|---|
| 44 |  . S YEARS=MONTHS\12
 | 
|---|
| 45 |  . S MONTH=MONTHS#12
 | 
|---|
| 46 |  . I MONTHS<1 D
 | 
|---|
| 47 |  . . S YEARS=YEARS-1
 | 
|---|
| 48 |  . . I MONTH=0 S MONTH=12
 | 
|---|
| 49 |  . S YEAR=$E(IDATE,1,3)+YEARS
 | 
|---|
| 50 |  . S MONTH=$TR($J(MONTH,2)," ","0")
 | 
|---|
| 51 |  . S ZDAY=$E(IDATE,6,7) ; Now make sure month may have 31 days...
 | 
|---|
| 52 |  . I ZDAY="31","/04/06/09/11/"["/"_MONTH_"/" S ZDAY="30" ; We'll check Feb later.
 | 
|---|
| 53 |  . S RESULT=YEAR_MONTH_ZDAY
 | 
|---|
| 54 |  E  S RESULT=($E(IDATE,1,3)+QUAN)_$E(IDATE,4,7) ; (TYPE=Y)
 | 
|---|
| 55 |  ; Now we need to check for Feb 29,30,31.    Any year divisible by 4 is a
 | 
|---|
| 56 |  I $E(RESULT,4,5)="02",$E(RESULT,6,7)>28 D  ;leap year.  However, if the
 | 
|---|
| 57 |  . S YEAR=$E(RESULT,1,3) ;year is a century year, it
 | 
|---|
| 58 |  . I YEAR#4=0 D  ;must also be divisible by 400.
 | 
|---|
| 59 |  . . I YEAR#100=0 S RESULT=YEAR_"02"_$S((YEAR+100)#400=0:"29",1:"28")
 | 
|---|
| 60 |  . . E  S RESULT=YEAR_"0229"
 | 
|---|
| 61 |  . E  S RESULT=YEAR_"0228"
 | 
|---|
| 62 |  Q RESULT
 | 
|---|
| 63 | DATEEOM(IDATE) ;
 | 
|---|
| 64 |  ; Given a FileMan date (yyymmdd), this function returns the
 | 
|---|
| 65 |  ; end-of-month date for the month of the given date.
 | 
|---|
| 66 |  ;
 | 
|---|
| 67 |  ; Example:  S EOM=$$DATEEOM("2940411")
 | 
|---|
| 68 |  ;           ...sets EOM to the last date in April: "2940430"
 | 
|---|
| 69 |  ;
 | 
|---|
| 70 |  Q $$DATEMATH($$DATEMATH($E(IDATE,1,5)_"01","1M"),"-1D")
 | 
|---|
| 71 | DATEFMT(IDATE,TYPEFMT,CHAR) ;
 | 
|---|
| 72 |  ; Given a FileMan date (yyymmdd), and optionally, the type of format
 | 
|---|
| 73 |  ; desired, and the character to be used, this function returns a
 | 
|---|
| 74 |  ; formatted date.
 | 
|---|
| 75 |  ;
 | 
|---|
| 76 |  ; IDATE    the FileMan date to format
 | 
|---|
| 77 |  ; TYPEFMT  1 = mm/dd/yy (default)
 | 
|---|
| 78 |  ;          2 = dd/mm/yy
 | 
|---|
| 79 |  ;          3 = dd mmm yy
 | 
|---|
| 80 |  ;          4 = mm/dd/yyyy ;**MOD,SD/AB,1/27/98, 4-digit year (YR 2000 Compliancy)
 | 
|---|
| 81 |  ; CHAR     the character to use as the separator (default="/")
 | 
|---|
| 82 |  ;
 | 
|---|
| 83 |  ; Example:  W !,$$DATEFMT("2940411",1,"/")
 | 
|---|
| 84 |  ;            ... returns 04/11/94
 | 
|---|
| 85 |  ;
 | 
|---|
| 86 |  S:'$D(TYPEFMT) TYPEFMT=1
 | 
|---|
| 87 |  S:'$D(CHAR) CHAR="/"
 | 
|---|
| 88 |  I TYPEFMT=1 Q $E(IDATE,4,5)_CHAR_$E(IDATE,6,7)_CHAR_$E(IDATE,2,3)
 | 
|---|
| 89 |  I TYPEFMT=2 Q $E(IDATE,6,7)_CHAR_$E(IDATE,4,5)_CHAR_$E(IDATE,2,3)
 | 
|---|
| 90 |  I TYPEFMT=3 Q +$E(IDATE,6,7)_" "_$P("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",",",$E(IDATE,4,5))_" "_$E(IDATE,2,3)
 | 
|---|
| 91 |  ;**MOD,SD/AB,1/27/98, Added TYPEFMT=4 to return 4-digit year
 | 
|---|
| 92 |  I TYPEFMT=4 Q $E(IDATE,4,5)_CHAR_$E(IDATE,6,7)_CHAR_(1700+$E(IDATE,1,3))
 | 
|---|
| 93 |  Q "???"
 | 
|---|