  DCL delta and absolute time math? 
 The Question is:
 
Hello Wizard,
 
My question is about DCL.
As far as I know F$CVTIME only accepts 1 time stamp and 1 delta time to
 calculate a new timestamp.
My question is:
Having two different time stamps.
How can I calculate the "Delta time"?
 
 
 The Answer is:
 
  Math.  There is no direct supported DCL-level tool that provides the
  delta time between two specified absolute times.  (This calculation
  is possible using RTL calls and an image, or using a DCL procedure,
  of course.)
 
  The attached example DCL procedures can (do) have limits on the ranges
  of absolute time values permited (correctly handled).  The OpenVMS
  Wizard generally recommends using an image for time calculations --
  the image can be designed to read and to create DCL symbols for easier
  integration into the DCL command procedure(s) that call it.
 
  Here are some examples (each with its own limitations) of manipulating
  time values solely from DCL:
 
	--
 
$file_time = f$cvtime(f$file("sys$login:login.com","CDT"),"comparison")
$five_minutes_ago = f$cvtime("-0-00:05:00","comparison")
 
$if file_time .lts. five_minutes_ago then write sys$output "Its too old"
 
	--
 
$ start_time = f$cvtime(,,"TIME")
 
$ wait 00:00:01 ! for example
 
$ stop_time  = f$cvtime(,,"TIME")
$ elapsed_time = f$cvtime(stop_time + "-" + start_time,,"TIME")
 
$ write sys$output elapsed_time
$ exit
 
	--
 
$!
$!  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 &gt; T1, if true, swap times and note sign change
$!
$ sign="+"
$ IF F$CVTIME(t1).LTS.F$CVTIME(t0)
$ THEN
$   sign="-"
$   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
$!
$! Subroutine FindUnit will perform a binary search looking for the
$! highest T0+delta which is less than T1 at the granularity of the
$! selected unit.
$!
$ hrs=0
$ mins=0
$ secs=0
$ hunds=0
$ ct1=F$CVTIME(t1)
 
$ hrs=23
$ unit="hrs"
$ GOSUB FindUnit
 
$ mins=59
$ unit="mins"
$ GOSUB FindUnit
 
$ secs=59
$ unit="secs"
$ GOSUB FindUnit
 
$ hunds=99
$ unit="hunds"
$ GOSUB FindUnit
 
$ delta==F$FAO("!1AS!4ZL-!2ZL:!2ZL:!2ZL.!2ZL",sign,ddays,hrs,mins,secs,hunds)
$ EXIT
$ BadTime: EXIT 5
 
 
$ FindUnit:
$ m='unit'
$ d=m+1
$ UnitLoop:
$   IF F$CVTIME(F$FAO("!AS+!4ZL-!2ZL:!2ZL:!2ZL.!2ZL",-
		t0,ddays,hrs,mins,secs,hunds)).GTS.ct1
$   THEN
$     sgn="-"
$   ELSE
$     IF d.LE.1 THEN RETURN
$     sgn="+"
$   ENDIF
$   d=(d+1)/2
$   'unit'='unit''sgn'd
$   IF 'unit'.LT.0 THEN 'unit'=0
$   IF 'unit'.GT.m THEN 'unit'=m
$ GOTO UnitLoop
 
