[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference noted::hackers_v1

Title:-={ H A C K E R S }=-
Notice:Write locked - see NOTED::HACKERS
Moderator:DIEHRD::MORRIS
Created:Thu Feb 20 1986
Last Modified:Mon Aug 03 1992
Last Successful Update:Fri Jun 06 1997
Number of topics:680
Total number of notes:5456

594.0. "Time math please..." by AUNTB::BRILEY () Mon Nov 02 1987 14:42

    Does anyone out there have some coding examples of how to find the
    delta time between two absolute times.  More generally some examples
    of how to add and subtract absolute and delta times.  More specifically
    I have several pairs of absolute times.  I would like to find the
    difference between each pair, and compute the sum of all the
    differences.  
    
    Fortran examples are preferred but all other languages are accepted.
    
    Thanks,
    Rob
T.RTitleUserPersonal
Name
DateLines
594.1Pointer LIB$ manualUSHS01::BLANDOReality, what a concept!Mon Nov 02 1987 18:048
    Sorry, I don't have examples on the E-net to pull.  But it is trivial,
    use the LIB$ADDX and LIB$SUBX routines to do your arithmetic.  Then,
    all you have to remember is that VMS uses the sign bit to determine
    if it is a delta time or an absolute time.  So get your delta times
    negative.
    
    FJBlando
    (Who has done it many times)
594.2In this conference?TOOK::HEFFERNANACCVIO masterMon Nov 02 1987 18:404
There is an bunch of code around for this.  I thought I saw it posted in
this file a while back.  If I get a chance, I'll look for it.


594.3an exampleDYO780::DYSERTBarry DysertTue Nov 03 1987 11:43135
	PROGRAM FUTURE
C ------------------------------------------------------------------------
C 	  This program calculates a future date from a given date.  The
C	  user specifies a base date and how many days future to go.
C	  The program calculates this future date and reports what it
C	  will be.
C
C 	  AUTHOR:  Barry D. Dysert
C ------------------------------------------------------------------------

	IMPLICIT INTEGER*4 (A-Z)

	INTEGER*4 timadr_q(2), future_q(2), addend_q(2), offset_q(2)
	INTEGER*4 srcdsc_l2, dstdsc_l2

	INTEGER*2 srcdsc_w1, dstdsc_w1

	BYTE srcdsc(8), dstdsc(8)

	CHARACTER ndays_t*12, offset_t*12, prod_t*63, timbuf_t*23

	LOGICAL*1 tenflag

	EQUIVALENCE (srcdsc_w1, srcdsc(1)), (srcdsc_b3, srcdsc(3))
	EQUIVALENCE (srcdsc_b4, srcdsc(4)), (srcdsc_l2, srcdsc(5))
	EQUIVALENCE (dstdsc_w1, dstdsc(1)), (dstdsc_b3, dstdsc(3))
	EQUIVALENCE (dstdsc_b4, dstdsc(4)), (dstdsc_l2, dstdsc(5))

	EXTERNAL DSC$K_DTYPE_Q, DSC$K_DTYPE_T, DSC$K_CLASS_S

C ------------------------------------------------------------------------

	offset_t='864000016384'	! there are 864000016384 units in 1 day
	offset_q(1)=711573504
	offset_q(2)=201

C -----	  get base date

10	TYPE 400
400	FORMAT(/'$Enter date (dd-mmm-yyyy): ')
	READ(*,401,END=99) timbuf_t
401	FORMAT(a)

C	  convert it to system time

	status=STR$UPCASE(timbuf_t,timbuf_t)
	IF (.not. status) CALL LIB$STOP(%val(status))

	length=INDEX(timbuf_t,' ')-1
	IF (length .le. 0) length=LEN(timbuf_t)

	status=SYS$BINTIM(timbuf_t(1:length),timadr_q)
	IF (.not. status) CALL LIB$STOP(%val(status))

C -----	  get number of days future

	TYPE 402
402	FORMAT('$How many days future?     ')
	READ(*,*,END=99) ndays

C -----
C -----	  future_q date will be calculated as:
C
C	  Q_fut_date = Q_given_date + ndays*864000016384
C
C	  the kicker is that in order to use STR$MUL, ndays must be
C	  converted to a decimal string (via OTS$CVT_L_TI); then
C	  convert the product to a quadword (via LIB$CVT_DX_DX); then
C	  add this quadword to the given_date (via LIB$ADDX).
C -----
C -----	  if ndays is a multiple of 5, CVT_L_TI won't tack the extra
C -----	  zeros on the end; instead it will set prodexp; it would then be
C -----	  a pain to tack the zeros on ourselves, so to get around it, just
C -----	  make sure ndays isn't a multiple of 5.  We'll add 1 to it if it
C -----	  is, and then subtract the offset after everything's done, just
C -----	  before the ASCTIM.

	tenflag=.FALSE.
	IF (MOD(ndays,5) .eq. 0) THEN
	   ndays=ndays+1
	   tenflag=.TRUE.
	ENDIF

C -----	  convert ndays to string

	status=OTS$CVT_L_TI(ndays,ndays_t,%val(12))
	IF (.not. status) CALL LIB$STOP(%val(status))

C -----	  multiply ndays by offset

	status=STR$MUL(0,0,ndays_t,0,0,offset_t,prodsign,prodexp,prod_t)
	IF (.not. status) CALL LIB$STOP(%val(status))

C -----	  convert the result string to a quadword

	srcdsc_w1=63				! length
	srcdsc_b3=%LOC(DSC$K_DTYPE_T)		! data type T
	srcdsc_b4=%LOC(DSC$K_CLASS_S)		! class S
	srcdsc_l2=%LOC(prod_t)			! address to be converted

	dstdsc_w1=8				! length
	dstdsc_b3=%LOC(DSC$K_DTYPE_Q)		! data type Q
	dstdsc_b4=%LOC(DSC$K_CLASS_S)		! class S
	dstdsc_l2=%LOC(addend_q)		! address of destination

	status=LIB$CVT_DX_DX(srcdsc,dstdsc)
	IF (.not. status) CALL LIB$STOP(%val(status))

C -----	  now add the addend_q to the given date to produce future_q date

	status=LIB$ADDX(addend_q,timadr_q,future_q)
	IF (.not. status) CALL LIB$STOP(%val(status))

C -----	  if ndays was a multiple of 5, we added an extra day so now we
C -----	  must subtract off the offset to get back to what we should have

	IF (tenflag) THEN
	   status=LIB$SUBX(future_q,offset_q,future_q)
	   IF (.not. status) CALL LIB$STOP(%val(status))
	ENDIF

C -----
C -----	  convert system time of future_q date back to ascii for output
C -----

	status=SYS$ASCTIM(,timbuf_t,future_q,%val(0))
	IF (.not. status) CALL LIB$STOP(%val(status))
	TYPE 403, timbuf_t(1:11)
403	FORMAT(' future date is ',a)
	GO TO 10

C -----	  bye bye

99	CALL EXIT
	END
594.4ATPS::MALLORYSPM V3.2 or bust...Fri Nov 06 1987 21:244
    Or you can use V5. There are LIB$SUB_TIMES and other neato
    runtime library routines for dealing with times.
    
    Kevin
594.5if you need v4NEWVAX::CRITZDon't shuffle my stack, I had 4 aces!Tue Nov 10 1987 17:467
    Also, instead of messing with trying to change the sign, you can
    use LIB$DAY, LIB$EMUL and SYS$FAO (in that order) to convert the
    final delta time into something printable.  Look at the source for
    the accounting utility for more info (or I can post a plagiarized
    version in PASCAL).
    
    -r