[comp.os.vms] Calculating Elapsed Time From DCL.

xrjjm%scint.span@VLSI.JPL.NASA.GOV (08/05/87)

Comment:   Begin User Supplied Mail Headers.
*Site:     NASA Goddard Space Flight Center - Greenbelt, Maryland, USA.
*Position: 76 Deg. 52' 28.5" West, 38 Deg. 59' 59.8" North.
*From:     John J. McMahon, Systems Programmer, STX - ST Systems Corporation.
*Project:  COBE Science Data Room (CSDR), Code 401.1
*Reply-To: (Arpa-Internet)       XRJJM%CSDR.SPAN@JPL-VLSI.ARPA [Old Format]
*Reply-To: (Arpa-Internet)       XRJJM%CSDR.SPAN@VLSI.JPL.NASA.GOV [New Format]
*Reply-To: (Bitnet)              ZMJJM@SCFVM
*Reply-To: (Span/Physnet/Hepnet) 6173::XRJJM = CSDR::XRJJM (Node 6.29)
*Reply-To: (TEXnet)              UTADNX::UTSPAN::CSDR::XRJJM


Lately I have been playing with the various F$xTIME commands that DCL
offers and I have noticed a couple of things that either are shortcomings,
or more likely things I have missed somewhere.

The first is converting a "Comparison" time to an "Absolute" time.  The
only difference I can find is that "Comparison" times use numeric
months, while "Absolute" uses JAN, FEB, MAR... etc.

I have a routine that wants to calculate a date 2 months back.  I take
an Absolute time as input, Convert it to Comparison, perform a calculation
(Month - 2)... then what ?  How do I convert it back to absolute ?  (In DCL).
I have considered using Delta times (Subtract 60 days or something similar)
but that doesn't fit my bill for accuracy.  I ruled out a HLL because this was 
supposed to be a Quick and Dirty job...

My second time question is, how does one calculate a delta time between two
dates (also in DCL).  I am primarily concerned with the number of days
between two dates, but knowing how to figure it out to the second would be
nice.

I have solved both of these problems already... I am just looking for the
more elegant solution.

--- Ok, next problem...  Lately I haven't seen any mail from INFO-VAX, and I
am trying to track down all of the possible failure points.  If you have
have sent mail to INFO-VAX lately, AND gotten a 'failed' message on my
address (xrjjm%csdr.span@jpl-vlsi.arpa) could you try and send me a
copy of the mail headers, or send me some mail describing the problem.
(If you can't get it to the address above, send it to ZMJJM@SCFVM.BITNET,
Internet: ZMJJM@SCFVM.BITNET@WISCVM.WISC.EDU)

Thanks & Regards,
^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v^v
John J. McMahon (Fast-Eddie)                     
Disclaimer: Views expressed in this letter are my own, 
            and are not meant to represent the views of my employers.

u3369429@murdu.OZ (Michael Bednarek) (08/07/87)

In article <870805075119.03q@VLSI.JPL.NASA.GOV> xrjjm%scint.span@VLSI.JPL.NASA.GOV writes:
> [Things about F$CVTIME]
>I have a routine that wants to calculate a date 2 months back.  I take
>an Absolute time as input, Convert it to Comparison, perform a calculation
>(Month - 2)... then what ?  How do I convert it back to absolute ?  (In DCL).
>I have considered using Delta times (Subtract 60 days or something similar)
>but that doesn't fit my bill for accuracy.  I ruled out a HLL because this was 
>supposed to be a Quick and Dirty job...

Well, this might not be the precise answer to your problems, but as I didn't
feel much like doing something productive this morning, I translated two
subroutines which deal with dates from Fortran to DCL.

One, JULIAN, takes a Gregorian date (dd-MON-yyyy) and returns a) the Julian
daynumber within that year, b) a Julian day number since 1-Jan-0001.
These day numbers can then be used to perform some calculations.

Its sister (brother ?) routine, GREGOR, takes b) from JULIAN and returns
a Gregorian date.

Now, anybody interested in a routine which calculates the date of easter
(a la D. Knuth) for any year?

....................... Cut between dotted lines and save ......................
$!..............................................................................
$! VAX/VMS archive file created by VMS_SHAR V-4.03 05-Aug-1987
$! which was written by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au)
$! To unpack, simply save and execute (@) this file.
$!
$! This archive was created by U3369429 (Michael Bednarek)
$!      on Friday 7-AUG-1987 15:50:09.27
$!
$! It contains the following 1 file:
$! JULGREG.COM
$!==============================================================================
$ Set Symbol/Scope=(NoLocal,NoGlobal)
$ Version=F$GetSYI("VERSION") ! See what VMS version we have here:
$ If Version.ges."V4.4" then goto Version_OK
$ Write SYS$Output "Sorry, you are running VMS ",Version, -
		", but this procedure requires V4.4 or higher."
$ Exit 44
$Version_OK: CR[0,8]=13
$ Pass_or_Failed="failed!,passed."
$ Goto Start
$Convert_File:
$ Read/Time_Out=0/Error=No_Error1/Prompt="creating ''File_is'" SYS$Command ddd
$No_Error1: Define/User_Mode SYS$Output NL:
$ Edit/TPU/NoSection/NoDisplay/Command=SYS$Input/Output='File_is' -
	VMS_SHAR_DUMMY.DUMMY
f:=Get_Info(Command_Line,"File_Name");b:=Create_Buffer("",f);
o:=Get_Info(Command_Line,"Output_File");Set (Output_File,b,o);
Position (Beginning_of(b));Loop x:=Erase_Character(1); Loop ExitIf x<>"V";
Move_Vertical(1);x:=Erase_Character(1);Append_Line;Move_Horizontal
(-Current_Offset);EndLoop;Move_Vertical(1);ExitIf Mark(None)=End_of(b)
EndLoop;Exit;
$ Delete VMS_SHAR_DUMMY.DUMMY;*
$ Checksum 'File_is
$ Success=F$Element(Check_Sum_is.eq.CHECKSUM$CHECKSUM,",",Pass_or_Failed)+CR
$ Read/Time_Out=0/Error=No_Error2/Prompt=" CHECKSUM ''Success'" SYS$Command ddd
$No_Error2: Return
$Start:
$ File_is="JULGREG.COM"
$ Check_Sum_is=1148729702
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X$ Verify='F$Verify(0)
X$! Playing around with Julian and Gregorian dates
X$ Facility_Name=	"JULGREG"
X$ Facility_Version=	"V-1.00 07-Aug-1987"
X$!
X$!Michael Bednarek		u3369429@{murdu.oz.au | ucsvc.dn.mu.oz.au}
X$!Institute of Applied Economic	-- or --
X$!  and Social Research (IAESR)	...{UUNET.UU.NET | seismo.CSS.GOV}!munnari!
X$!Melbourne University		   {murdu.oz | ucsvc.dn.mu.oz}!u3369429
X$!Parkville 3052, Phone : +61 3 344 5744
X$!AUSTRALIA
X$!
X$! Copyright (c) 1987, by Michael Bednarek
X$! The distribution of this file is unrestricted as long as this notice
X$! remains intact.
X$!
X$! Usage: @JULGREG Date1 Date2
X$!
X$ Say="Write SYS$Output"
X$ Ask="Inquire/NoPunctuation"
X$ Say Facility_Name," ",Facility_Version
X$ Say ""
X$!
X$ On Warning then Exit
X$ If P1.eqs."" then Ask P1 "Enter Date 1: "
X$ P1=F$CVTime(P1,"Absolute")
X$ If P2.eqs."" then Ask P2 "Enter Date 2: "
X$ P2=F$CVTime(P2,"Absolute")
X$ Call Julian "''P1'" YJDay1 AJDay1
X$ Call Julian "''P2'" YJDay2 AJDay2
X$ Say F$FAO("The difference is !SL day!%S",AJDay2-AJDay1)
X$! Testing Gregor:
X$ Call Gregor 'AJDay1 Date1
X$ Call Gregor 'AJDay2 Date2
X$ Say "GREGOR returns: ",Date1," and ",Date2
X$ Exit
X$Julian: Subroutine
X$ On Warning then Exit
X$! Converts Gregorian Date into Julian Day
X$! This is a straight translation from an old Fortran routine of mine.
X$ M2=" 0,31,59,90,120,151,181,212,243,273,304,334"
X$! Input:
X$! P1 = Date in absolute format as returned from F$CVTIME
X$!
X$! Output:
X$! P2 = YJDay = Julian Day in this year
X$! P3 = AJDay = Julian Day since 1-Jan-0001 A.D
X$!              (can be used as input to GREGOR)
X$!
X$ Year =F$Integer(F$CVTime(P1,,"Year"))
X$ Month=F$Integer(F$CVTime(P1,,"Month"))
X$ Day  =F$Integer(F$CVTime(P1,,"Day"))
X$!
X$! detect leap year
X$ Leap=Year-Year/400*400.eq.0 .or. -
X       Year-Year/100*100.ne.0 .and. Year-Year/4*4.eq.0
X$!
X$! Calculate this year's Julian Day
X$ 'P2==F$Integer(F$Element(Month-1,",",M2))+Day
X$ If Month.gt.2 .and. Leap then 'P2=='P2+1
X$!
X$! Calculate the Absolute Julian Day
X$ Year=Year-1
X$ 'P3==Year*365+Year/4-Year/100+Year/400+'P2
X$ EndSubroutine
X$Gregor: Subroutine
X$ On Warning then Exit
X$! Converts Julian Day into Gregorian Date
X$! Although this routine is not required in this context, I thought I'd
X$! include it anyway.
X$! Input:
X$! P1 = AJDay = Julian Day since 1-Jan-0001 A.D. (as obtained from JULIAN)
X$!
X$! Output:
X$! P2 = Date in absolute  format (dd-MON-yyyy)
X$ M1=" 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31"
X$ M3="Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec"
X$!
X$ i=P1
X$ im=i/146097
X$ Year=im*400
X$ i=i-im*146097
X$!
X$ im=i/36524
X$ Year=Year+im*100
X$ i=i-im*36524
X$!
X$ im=i/1461
X$ Year=Year+im*4
X$ i=i-im*1461
X$!
X$ im=(i+364)/365-1
X$ Year=Year+im
X$!
X$ YJDay=P1-Year*365-Year/4+Year/100-Year/400
X$ Year=Year+1
X$!
X$ Leap=Year-Year/400*400.eq.0 .or. -
X       Year-Year/100*100.ne.0 .and. Year-Year/4*4.eq.0
X$!
X$ If Leap .and. YJDay.gt.59 then M1[5,2]:="29"
X$ n1=0
X$ Month=0
X$Loop:
X$ Month=Month+1
X$ n2=n1
X$ n1=n1+F$Integer(F$Element(Month-1,",",M1))
X$ If YJDay.le.n1 then goto Done
X$ If Month.lt.12 then goto Loop
X$Done:
X$ Day=YJDay-n2
X$ Month=F$Element(Month-1,",",M3)
X$ 'P2==F$CVTime("''Day'-''Month'-''Year'","Absolute","Date")
X$ EndSubroutine
$ GoSub Convert_File
$ Exit

d2b@rayssd.RAY.COM (Donald A. Borsay) (08/21/87)

In article <870805075119.03q@VLSI.JPL.NASA.GOV> 
xrjjm%scint.span@VLSI.JPL.NASA.GOV (John McMahon writes:
>
>Lately I have been playing with the various F$xTIME commands that DCL
>offers and I have noticed a couple of things that either are shortcomings,
>or more likely things I have missed somewhere.
...
>My second time question is, how does one calculate a delta time between two
>dates (also in DCL).  I am primarily concerned with the number of days
>between two dates, but knowing how to figure it out to the second would be
>nice.

Ok, John and other Netlanders, here's a program I wipped up to assist me in
some benchmark DCL procedures I did a while back.  Simply cut at the
dotted line and replace all $$ with a tab (I here tabs cause some mailers
pain).  I know this works with Fortran 4.4 and VMS 4.4.  Enjoy!!
----
Don    |Raytheon Company, Submarine Signal Division, Portsmouth, RI
Borsay |ARPAnet: d2b%rayssd.RAY.COM@a.cs.uiuc.edu
       |UUCPmail: {allegra, decvax!brunix, linus!raybed2}!rayssd!d2b
----------- CUT HERE ---------- CUT HERE ------- CUT HERE --------------

$$program delta	!delta_return = p1 - p2
$$implicit none
c*************************************************************************
c PROGRAM:$$DELTA
c WRITTEN BY:$$Don Borsay
c 
c DELTA takes p1 and p2 are absolute ascii times, and creates the DCL
c global symbol delta_return as the delta ascii time difference of
c P1 - P2
c*************************************************************************

$$integer	sys$bintim,	!Converts ascii time to binary
     x$$	sys$asctim,	!Converts binary time to ascii
     x$$	lib$subx,	!Subtracts binary of arbitrary length
     x$$	lib$get_foreign,!Get parameters from foreign command line
     x$$	index,		!Position of substring (p2) in string (p1)
     x$$	lib$set_symbol	!Generate DCL symbol for return value

$$integer	time_a(2), 	!Binary form of p1
     x$$	time_b(2), 	!Binary form of p2
     x$$	delta_return(2),!Binary form of subtracted result
     x$$	string_length*2 !Length of string_delta_return
     $$logical	status*4	!Status code returned from system routines
$$character string_a*64, 	!Character form of p1
     x$$	string_b*64, 	!Character form of p2
     x$$	string_delta_return*64 !Character form of subtracted result

$$integer i
$$character*80 line

$$status = lib$get_foreign(line)
$$if (line.eq.' ') then
$$  status = lib$get_foreign(string_a,'Enter 1st absolute time: ')
$$  status = lib$get_foreign(string_b,'Enter 2nd absolute time: ')
$$else
$$  i = index (line,',')
$$  string_a = line(1:i-1)
$$  string_b = line(i+1:)
$$end if
$$if (string_a.eq.' '.and.string_b.eq.' ') call exit
$$status = sys$bintim(string_a,time_a)
$$if (.not.status) 
     x$$	call error('Converting 1st parameter',status)
$$status = sys$bintim(string_b,time_b)
$$if (.not.status) 
     x$$	call error('Converting 2nd parameter',status)
$$status = lib$subx(time_B,time_A,delta_return,2)
$$if (.not.status) 
     x$$	call error('Performing p1 - p2',status)
$$status = sys$asctim(string_length,string_delta_return,
     x$$	delta_return,%val(0))
$$if (.not.status) 
     x$$	call error('Generating return ascii time',status)
$$status = lib$set_symbol('DELTA_RETURN',
     x$$	string_delta_return(1:string_length))
$$if (.not.status) 
     x$$	call error('DELTA_RETURN could not be created',status)
$$call exit(status)
$$end

$$subroutine error(message,code)

$$integer	lib$signal	!Signals error, producing error messages

$$integer	code,		!Error message code returned from routines
     x$$	len		!Built in routine to return length of string
$$character message*(*)	!Error message to be outputted on SYS$OUTPUT

$$print 10,message
10$$format(1x,'Error ',a<len(message)>,', reason follows:')
$$call lib$signal(%val(code))
$$return
$$end
-- 
Don    |Raytheon Company, Submarine Signal Division, Portsmouth, RI
Borsay |ARPAnet: d2b%rayssd.RAY.COM@a.cs.uiuc.edu
       |UUCPmail: {allegra, decvax!brunix, linus!raybed2}!rayssd!d2b