$! $! Procedure to find the delta time between two times. Uses successive $! approximation on each of the fields YEAR MONTH DAY HOUR MINUTES SECONDS $! HUNDREDTHS $! $ IF p1.EQS."" THEN INQUIRE p1 "T0" $ IF p2.EQS."" THEN INQUIRE p2 "T1" $ ON WARNING THEN GOTO BadTime $! $! Convert to full format absolute time $! $ t0=F$CVTIME(p1,"ABSOLUTE") $ t1=F$CVTIME(p2,"ABSOLUTE") $! $! Check for T0 > T1, swap times and note sign change $! $ sgn="+" $ IF F$CVTIME(t1).LTS.F$CVTIME(t0) $ THEN $ sgn="-" $ t0=F$CVTIME(p2,"ABSOLUTE") $ t1=F$CVTIME(p1,"ABSOLUTE") $ ENDIF $! $! Init variables $ ddays=0 $! $! Get the right year $! $ yr1=F$CVTIME(t1,,"YEAR") $ yr0=F$CVTIME(t0,,"YEAR") $ IF yr0.EQS.yr1 THEN GOTO GetMonth $! $! Find enough days to add to T0 to make the years the same $! $ ddays=(F$INTEGER(yr1)-F$INTEGER(yr0))*365 $ $ YearLoop: $ yr0=F$CVTIME("''t0'+''ddays'-0",,"YEAR") $ IF yr0.EQS.yr1 THEN GOTO GetMonth $ IF yr0.GTS.yr1 $ THEN $ ddays=ddays-1 $ ELSE $ ddays=ddays+1 $ ENDIF $ GOTO YearLoop $ $! Adjust days so that T0+ddays is within the same month as T1 $! $ GetMonth: $ mth1=F$CVTIME(t1,,"MONTH") $ mth0=F$CVTIME("''t0'+''ddays'-0",,"MONTH") $ IF mth0.EQS.mth1 THEN GOTO GetDay $ ddays=ddays+(F$INTEGER(mth1)-F$INTEGER(mth0))*30 $ $ MonthLoop: $ mth0=F$CVTIME("''t0'+''ddays'-0",,"MONTH") $ IF mth0.EQS.mth1 THEN GOTO GetDay $ IF mth0.GTS.mth1 $ THEN $ ddays=ddays-1 $ ELSE $ ddays=ddays+1 $ ENDIF $ GOTO MonthLoop $ $ GetDay: $ day1=F$CVTIME(t1,,"DAY") $ DayLoop: $ day0=F$CVTIME("''t0'+''ddays'-0",,"DAY") $ IF day0.EQS.day1 THEN GOTO GetTimes $ IF day0.GTS.day1 $ THEN $ ddays=ddays-1 $ ELSE $ ddays=ddays+1 $ ENDIF $ GOTO DayLoop $ $ GetTimes: $! Now we want to approach the exact delta time from below. Start $! by making sure our current approximation is less than the correct $! time. It can only be out by 1 day maximum $! $ IF F$CVTIME("''t0'+''ddays'-0").GTS.F$CVTIME(t1) THEN ddays=ddays-1 $! $! Each loop will start with the rollover value of the time unit and $! count down (decrement at top) this makes a neater DCL structure. $! Although this might mean a significant number of iterations (up to $! 100 for hundredths), it's easier to code this way. Also note that a true $! binary search cannot be implemented as time format does not permit $! the upper boundary of the time unit (24 for hours, 60 for minutes etc) $! $ hrs=24 $ HourLoop: $ hrs=hrs-1 $ IF F$CVTIME("''t0'+''ddays'-''hrs'")- .GTS.F$CVTIME(t1) THEN GOTO HourLoop $ mins=60 $ MinsLoop: $ mins=mins-1 $ IF F$CVTIME("''t0'+''ddays'-''hrs':''mins'")- .GTS.F$CVTIME(t1) THEN GOTO MinsLoop $ secs=60 $ SecsLoop: $ secs=secs-1 $ IF F$CVTIME("''t0'+''ddays'-''hrs':''mins':''secs'")- .GTS.F$CVTIME(t1) THEN GOTO SecsLoop $ hunds=100 $ HundsLoop: $ hunds=hunds-1 $ h=F$FAO("!2ZL",hunds) ! So that .1 means .01, not .10 $ IF F$CVTIME("''t0'+''ddays'-''hrs':''mins':''secs'.''h'")- .GTS.F$CVTIME(t1) THEN GOTO HundsLoop $ delta==F$FAO("!1AS!4ZL-!2ZL:!2ZL:!2ZL.!2ZL",sgn,ddays,hrs,mins,secs,hunds) $ t0=F$CVTIME(p1,"ABSOLUTE") $ t1=F$CVTIME(p2,"ABSOLUTE") $ IF F$CVTIME("''t0'''delta'").NES.F$CVTIME(t1) $ THEN $ WRITE SYS$OUTPUT "Error in delta time" $ SHOW SYM t0 $ SHOW SYM t1 $ SHOW SYM delta $ EXIT 5 $ ENDIF $ BadTime: EXIT