🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: vmsnet.sources
Article #102

Time functions, part 02/02

#102
From: Ed Wilts
Date: Fri, 04 Sep 1992 05:22
1204 lines
38442 bytes
Submitted-by: ewilts@galaxy.gov.bc.ca (Ed Wilts)
Posting-number: Volume 3, Issue 151
Archive-name: time_functions/part01

-+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+
X`09`09ELSEIF ( (BIN_SCR(2) + BIN_SCR(1)) .EQ. 0 ) THEN
X`09`09`09RESULT = 'YES'
X`09`09ELSE
X`09`09`09RESULT = 'NO'
X`09`09ENDIF
X`09`09GOTO 1999
XC
XC   ------------------------------------------------------------------------
V---
XC
X`09ELSEIF ( PARAM(OP2_1:OP2_2) .EQ. GREATER_THAN .OR.
X`091`09 PARAM(OP2_1:OP2_2) .EQ. '(GT)' ) THEN
XC
XC`09   Compare for greater than.
XC
X`09`09STATUS = LIB$SUBX( BIN_2, BIN_1, BIN_SCR, 2 )
X`09`09IF ( BIN_SCR(2) .LT. 0 ) THEN
X`09`09`09RESULT = 'YES'
X`09`09ELSE
X`09`09`09RESULT = 'NO'
X`09`09ENDIF
X`09`09GOTO 1999
XC
XC   ------------------------------------------------------------------------
V---
XC
X`09ELSEIF ( PARAM(OP2_1:OP2_2) .EQ. GREATER_THAN_EQUAL_TO .OR.
X`091`09 PARAM(OP2_1:OP2_2) .EQ. '(GE)' ) THEN
XC
XC`09   Compare for greater than or equal to.
XC
X`09`09STATUS = LIB$SUBX( BIN_2, BIN_1, BIN_SCR, 2 )
X`09`09IF ( BIN_SCR(2) .LT. 0 ) THEN
X`09`09`09RESULT = 'YES'
X`09`09ELSEIF ( (BIN_SCR(2) + BIN_SCR(1)) .EQ. 0 ) THEN
X`09`09`09RESULT = 'YES'
X`09`09ELSE
X`09`09`09RESULT = 'NO'
X`09`09ENDIF
X`09`09GOTO 1999
XC
XC   ------------------------------------------------------------------------
V---
XC
X`09ELSE
XC
XC`09   Invalid operator.
XC
X`09`09CALL LIB$STOP(TIME__INVOPR)
X`09ENDIF
X      ENDDO`09
XC
XC   ------------------------------------------------------------------------
V---
XC
XC   See if there are any additional parameters on the line.
XC
X1999`09CONTINUE
X`09STATUS = TIMEGET( PARAM(1:PARAM_S), OP3_1, OP3_2 )
X`09IF ( STATUS ) THEN
X`09`09CALL LIB$STOP(TIME__TOOMNYOPR)
X`09ENDIF
XC
XC   ------------------------------------------------------------------------
V---
XC
XC   Store the symbol in the symbol table, or output it to SYS$OUTPUT dependi
Vng
XC`09on whether a symbol was defined.
XC
X`09STATUS = STR$TRIM`20
X`091`09( RESULT, RESULT, RESULT_S )
X`09IF ( SYMBOL_S .NE. 0 ) THEN
X`09`09STATUS = LIB$SET_SYMBOL
X`091`09`09( SYMBOL(1:SYMBOL_S), RESULT(1:RESULT_S) )
X`09ELSE
X`09`09STATUS = LIB$PUT_OUTPUT ( RESULT(1:RESULT_S) )
X`09END IF`09
XC
XC   Exit.
XC
X`09CALL EXIT(status)
X`09END
$ CALL UNPACK TIME.FOR;1 2118724995
$ create 'f'
X! 23-Mar-83  FJN  Added keywords subtopic
X! 02-Apr-83  FJN  Added LASTMONTH and LASTWEEK keywords
X1 TIME
X The function of this command is to perform time calculation services.
X Format:
X
X         TIME `5B time-spec `5B (operator) time-spec`5D ... `5D
X
X By default if no operands are specified the command will display the
X current system time and the user's connect time.
X
X If only one operand is supplied, then instead of calculating the user's
X connect time the operand (which must be in absolute time format) will be`20
X subtracted from the current system time and that resulting delta time
X displayed along with the current system time.
X
X `5B`5D indicates optional.  () are required for the operator.
X '...' only valid for (+),(-),(*), & (/) operators
X
X The TIME symbol is defined by:
X
X`09TIME :== $ECSEXE:TIME
X
X2 Time-spec
X The times values which may be specified are absolute time,`20
X delta time, keyword for an absolute time or a positive
X integer value.
X
X3 Absolute_time
X Formats:
X
X    dd-mmm-yyyy`5B:`5D`5Bhh:mm:ss.ss`5D
X
X 1. If you specify both the date (dd-mmm-yyyy) and the time
X    (hh:mm:ss.ss), you may type the colon between the date and
X    the time or seperate them with a tab or a blank. `20
X
X    The lexical function 'F$TIME()' may be used to generate`20
X    the current time value (this returns the value with a blank
X    between the date and time fields). `20
X
X    On output there will always be a colon between the date and`20
X    the time of day fields.
X
X 2. If only the date is specified the system will supply the
X    current time of day for the missing time field.
X
X 3. If you specify a time of day you can truncate the time on`20
X    the right.  The truncated fields will be zero filled (See
X    point 4 if you wish to supply punctuation).
X
X 4. If you omit any of the fields but supply the punctuation marks
X    the system will supply the current system time values as`20
X    defaults (do not confuse this with truncation where the
X    punctuation marks are also omited; point 3).
X
X3 Delta_time
X Format
X
X    dd`5B-`5Dhh`5B:mm:ss.ss`5D
X
X When you specify a delta time value, you can truncate the time field
X on the right; you may also omit any of the variable fields, as long
X as you supply the punctuation marks.
X
X When any field is omitted from a delta time value, the system
X supplies a value of 0 for the field.
X
X3 Integer
X An positive integer value may also be specified.  The value must
X be within the range:
X`20
X    0 - 2147483647
X
X3 Keywords
X The following keywords represent certain absolute dates (the times
X are always 00:00:00.00):
X
X    YESTERDAY    yesterday's start.
X    TODAY        start of the current day.
X    TOMORROW     start of tomorrow.
X
X    THISMONTH    First day of the current month.
X    NEXTMONTH    First day of the next month.
X    LASTMONTH    First day of the previous month.
X
X    THISYEAR     January 1 of the current year.
X
X    THISWEEK     Monday of the current week (possibly today).
X    NEXTWEEK     Next Monday (first day of the next week).
X    LASTWEEK     Monday of the previous (full 7-day) week.
X
X2 Operator
X The operators available are addition, subtraction, multiplication,
X division, and comparison.
X The syntax for the operators are:
X
X     (+)    Addition
X     (-)    Subtraction
X     (*)    Multiplication
X     (/)    Division
X     (=)    Compare for equal to
X     (<>)   Compare for not equal to
X     (<)    Compare for less than
X     (<=)   Compare for less than or equal to
X     (>)    Compare for greater than
X     (>=)   Compare for greater than or equal to
X     (?)    General comparison
X
X The operator MUST be enclosed in parenthesis's.  This is to avoid`20
X syntax confusion with the '-' used in the time specifications.
X
X Note:  If any of the results yealds a negative time value the
X        absolute value of the calculation is displayed.
X
X3 Addition (+)
X This operator will add the two operands and return the result.
X Valid combinations and the type of result returned are shown
X below:
X
X     TIME   absolute_time (+) delta_time     -->  absolute_time
X     TIME   delta_time (+) absolute_time     -->  absolute_time
X     TIME   delta_time (+) delta_time        -->  delta_time
X     TIME   integer (+) integer              -->  integer
X
X3 Subtraction (-)
X This operator will subtract the two operands and return the
X result.  Valid combinations and the type of result returned
X are shown below:
X
X     TIME   absolute_time (-) absolute_time  -->  delta_time
X     TIME   absolute_time (-) delta_time     -->  absolute_time
X     TIME   delta_time (-) delta_time        -->  delta_time
X     TIME   integer (-) integer              -->  integer
X
X Note:  If any of the results yealds a negative value the
X        absolute value of the calculation is returned.
X
X3 Multiplication (*)
X This operator will multiply the two operands and return the
X result.  Valid combinations and the type of result returnd
X are shown below:
X
X     TIME   delta_time (*) integer           -->  delta_time
X     TIME   integer (*) delta_time           -->  delta_time
X     TIME   integer (*) integer              -->  integer
X
X3 Division (/)
X This operator will divide the two operands and return the
X result.  Valid combinations and the type of result returned
X are shown below:
X
X     TIME   delta_time (/) delta_time        -->  integer
X     TIME   delta_time (/) integer           -->  delta_time
X     TIME   integer (/) integer              -->  integer
X
X3 Comparison (?)
X This operator will compare the two operands and return the
X results of the comparison.
X
X     TIME   absolute_time       (?)      absolute_time
X
X                            GREATER_THAN
X                              EQUAL_TO
X                              LESS_THAN
X
X     TIME   delta_time       (?)      delta_time
X
X                         GREATER_THAN
X                           EQUAL_TO
X                           LESS_THAN
X
X3 EQ (=)
X This operator wil compare the two operands and return YES
X if they are equal and NO if they are not.
X
X     TIME   absolute_time  (=)   absolute_time
X     TIME   absolute_time  (EQ)   absolute_time
X
X     TIME   delta_time     (=)   delta_time
X     TIME   delta_time     (EQ)   delta_time
X
X3 NE (<>)
X This operator will compare the two operands and return YES
X if they are not equal and NO if they are equal.
X
X     TIME   absolute_time  (<>)   absolute_time
X     TIME   absolute_time  (NE)   absolute_time
X
X     TIME   delta_time     (<>)   delta_time
X     TIME   delta_time     (NE)   delta_time
X
X3 LT (<)
X This operator will compare the two operands and return YES
X if the first operand is less than the second operand,
X otherwise it will return NO.
X
X     TIME   absolute_time  (<)   absolute_time
X     TIME   absolute_time  (LT)   absolute_time
X
X     TIME   delta_time     (<)   delta_time
X     TIME   delta_time     (LT)   delta_time
X
X3 LE (<=)
X This operator will compare the two operands and return YES
X if the first operand is less than or equal to the second`20
X operand, otherwise it will return NO.
X
X     TIME   absolute_time  (<=)   absolute_time
X     TIME   absolute_time  (LE)   absolute_time
X
X     TIME   delta_time     (<=)   delta_time
X     TIME   delta_time     (LE)   delta_time
X
X3 GT (>)
X This operator will compare the two operands and return YES
X if the first operand is greater than the second operand,
X otherwise it will return NO.
X
X     TIME   absolute_time  (>)   absolute_time
X     TIME   absolute_time  (GT)   absolute_time
X
X     TIME   delta_time     (>)   delta_time
X     TIME   delta_time     (GT)   delta_time
X
X3 GE (>=)
X This operator will compare the two operands and return YES
X if the first operand is greater than or equal to the second
X operand, otherwise it will return NO.
X
X     TIME   absolute_time  (>=)   absolute_time
X     TIME   absolute_time  (GE)   absolute_time
X
X     TIME   delta_time     (>=)   delta_time
X     TIME   delta_time     (GE)   delta_time
X
X2 Qualifiers
X
X/DEBUG
X This option will show the intermediate results of a sequence of`20
X operations.  It also disables some internal error checking so`20
X the output may not be correct.
X
X/SYMBOL=symbol_name
X This option will cause the results of the calculation to be stored in
X the specified symbol instead of being displayed to the output device.
$ CALL UNPACK TIME.HLP;2 73615922
$ create 'f'
XC   ------------------------------------------------------------------------
V---
XC   TIMECNV.FOR - The function of this routine is to convert the absolute
XC`09time, delta time, or interger value character string passed into`20
XC`09a positive 64 bit binary value.  If the format is incorrect then the
XC`09status returned is even.
XC
XC`09Note:  The delta times will be converted to positive values.
XC
XC   Calling Procedure:
XC
XC`09status = TIMECNV( string, binary_value )
XC
XC   Entry Conditions:
XC
XC`09string - must contain the absolute time, the delta time or an integer
XC`09`09 character string (integer = 0 through 2147483647) or a
XC`09`09 recognized keyword name.
XC
XC   Exit Conditions:
XC
XC`09status = 3 if string is absolute time format.
XC`09       = 4 if invalid absolute time format.
XC`09       = 5 if string is delta time format.
XC`09       = 6 if invalid delta time format.
XC`09       = 7 if integer value.
XC`09       = 8 if invalid integer value.
XC
XC`09binary_value - contains the binary value of the value converted.
XC`09`09Both absolute times and delta times will be positive.
XC`09`09This variable must be 2 longword long.
XC
XC   ------------------------------------------------------------------------
V---
XC
X`09INTEGER*4 FUNCTION TIMECNV( STRING, BIN_VAL )
XC
X`09IMPLICIT INTEGER*4 (A-Z)
XC
X`09EXTERNAL`09OTS$_INPCONERR
XC
X`09PARAMETER`09DASH='-'
X`09PARAMETER`09COLON=':'
X`09PARAMETER`09BLANK=' '
X`09PARAMETER`09PERIOD='.'
XC
X`09CHARACTER*(*)`09STRING
X`09CHARACTER`09WORK*(32)
XC
X`09INTEGER*4`09TIMEKEY
XC
X`09INTEGER*4`09BIN_VAL(2)
X`09INTEGER*4`09ZERO(2) /0,0/
XC
XC   ------------------------------------------------------------------------
V---
XC
XC   Initialize the return code to integer value.
XC
X`09TIMECNV = 7
XC
XC   Determine if it is absolute, delta, or integer format.
XC`092 dashes is absolute.
XC`091 dash or (no dash and a colon) or (no dash and a period) is delta.
XC`09no dash and no colon and no period is and integer.
XC
X`09I = INDEX( STRING, DASH )
X`09IF ( I .NE. 0 ) THEN`09
X`09`09TIMECNV = 5
X`09`09J = INDEX( STRING(I+1:), DASH )
X`09`09IF ( J .NE. 0 ) THEN
X`09`09`09TIMECNV = 3
X`09`09ENDIF
X`09ENDIF
XC`20
X`09IF ( TIMECNV .EQ. 7 ) THEN
X`09`09IF ( (INDEX( STRING, COLON ) +`20
X`091`09      INDEX( STRING, PERIOD )) .NE. 0 ) TIMECNV = 5
X`09ENDIF
XC
XC   ------------------------------------------------------------------------
V---
XC
XC   Convert the time based on the type of time it is.
XC
X`09IF ( TIMECNV .EQ. 3 ) THEN
XC
XC`09   Absolute time; remove the colon from between the year and hour
XC `09`09if present.
XC
X`09`09B1 = INDEX( STRING, BLANK )
X`09`09IF ( B1 .EQ. 0 ) THEN
X`09`09`09B1 = INDEX( STRING, COLON )
X`09`09`09IF ( B1 .NE. 0 ) THEN
X`09`09`09`09STRING(B1:B1) = BLANK
X`09`09`09ENDIF
X`09`09ENDIF
XC
XC`09   If trailing fields of the time of day are missing supply 0's.
XC
X`09`09WORK = STRING
X`09`09IF ( B1 .NE. 0 ) THEN`09`09! no time; allow full subs.
X`09`09    L = LEN( STRING ) + 1
X`09`09    C1 = INDEX( WORK, COLON )
X`09`09    IF ( C1 .EQ. 0 ) THEN
X`09`09`09WORK(L:) = ':0:0.0'
X`09`09    ELSEIF ( INDEX( WORK(C1+1:), COLON ) .EQ. 0 ) THEN
X`09`09`09WORK(L:) = ':0.0'
X`09`09    ELSEIF ( INDEX( WORK, PERIOD ) .EQ. 0 ) THEN
X`09`09`09WORK(L:) = '.0'
X`09`09    ENDIF
X`09`09ENDIF
XC
XC`09   Convert to absolute binary time.
XC
X`09`09STATUS = SYS$BINTIM( WORK, BIN_VAL )
X`09`09IF ( .NOT. STATUS ) THEN
XC
XC`09`09    Specify return status of invalid absolute time format.
XC
X`09`09`09TIMECNV = 4
X`09`09ENDIF
XC
XC   ------------------------------------------------------------------------
V---
XC
X`09ELSEIF ( TIMECNV .EQ. 5 ) THEN
XC
XC`09   Delta time; remove the dash from between the days and the hour.
XC
X`09`09I = INDEX( STRING, DASH )
X`09`09IF ( I .NE. 0 ) THEN
X`09`09`09STRING(I:I) = BLANK
X`09`09ENDIF
XC
XC`09   Convert to delta binary time.
XC
X`09`09STATUS = SYS$BINTIM( STRING, BIN_VAL )
X`09`09IF ( .NOT. STATUS ) THEN
XC
XC`09`09    Specify return status of invalid delta time format.
XC
X`09`09`09TIMECNV = 6
X`09`09ENDIF
X`09`09STATUS = LIB$SUBX( ZERO, BIN_VAL, BIN_VAL, 2 )
XC
XC   ------------------------------------------------------------------------
V---
XC
X`09ELSEIF ( TIMEKEY(string, bin_val)) THEN
XC
XC Keyword was found, treat as an absolute time
XC
X`09`09timecnv = 3
X`09ELSE
XC
XC`09   Convert the integer value to binary.
XC
X`09`09STATUS = OTS$CVT_TI_L( STRING, BIN_VAL(1), %VAL(4), %VAL(3) )
X`09`09IF ( STATUS .EQ. %LOC(OTS$_INPCONERR) .OR.
X`091`09      BIN_VAL(1) .LT. 0 ) THEN
XC
XC`09`09   Specify return status of invalid integer value format.
XC
X`09`09`09TIMECNV = 8
X`09`09ENDIF
X`09`09BIN_VAL(2) = 0
X`09ENDIF
XC
XC   ------------------------------------------------------------------------
V---
XC
XC   Return
XC
X`09RETURN
X`09END
$ CALL UNPACK TIMECNV.FOR;1 2017346050
$ create 'f'
XC   ------------------------------------------------------------------------
V---
XC   TIMECUR.FOR - The function of this routine is to determine the current
XC`09system time and the processes current connect time.  The values are
XC`09converted to string data and returned as the function value of the
XC`09routine.
XC
XC   Calling Procedure:
XC
XC`09return_string = TIMECUR ( login_time )
XC
XC   Entry Conditions:
XC
XC`09login_time - This must be the time to subtract from the current system
XC`09`09time in order to get the delta time.  If zero is passed than
XC`09`09the process login time is used instead.
XC
XC   Exit Conditions:
XC
XC`09A character string with the current time and the current connect time
XC`09will be returned as the value of the function.
XC
XC`09The format of returned string is:
XC
XC`09`09TIMECUR = 'dd-mmm-yyyy:hh:mm:ss.hh<tab>dddd-hh:mm:ss.hh'
XC
XC`09Leading blanks will be included.
XC
XC   ------------------------------------------------------------------------
V---
XC
X`09CHARACTER*40 FUNCTION TIMECUR ( LOGINTIM )
XC
X`09IMPLICIT INTEGER*4 (A-Z)
XC
X`09PARAMETER`09ABSZ=23
X`09PARAMETER`09DELTAZ=16
X`09PARAMETER`09DASH='-'
X`09PARAMETER`09EQUAL=':='
X`09PARAMETER`09COLON=':'
X`09PARAMETER`09TAB='`09'
XC
X`09CHARACTER`09ABS_C*(ABSZ)
X`09CHARACTER`09JPI_LOGINTIM*(ABSZ)
X`09CHARACTER`09DELTA_C*(DELTAZ)
XC
X`09INTEGER*4`09ABS(2), ABS_S
X`09INTEGER*4`09LOGINTIM(2), LOGINTIM_S
X`09INTEGER*4`09DELTA(2), DELTA_S
XC
XC   ------------------------------------------------------------------------
V---
XC
XC   Fetch the processes login time.
XC
X`09IF ( LOGINTIM(1) .EQ. 0 ) THEN
X`09`09TIMECUR = JPI_LOGINTIM ( LOGINTIM, LOGINTIM_S )
X`09ENDIF
XC
XC   Fetch the current character system time.
XC
X`09CALL SYS$ASCTIM ( ABS_S, ABS_C, , %VAL(0) )
XC
XC   Convert the current system time to binary system time
XC
X`09CALL SYS$BINTIM ( ABS_C, ABS )
XC
XC   Subtract the login time from the current system time to get connect time
V.
XC`09Note: that the acutal calculation is done to yeald negative result
XC`09      because delta times are negative values.
XC
X`09CALL LIB$SUBX ( LOGINTIM, ABS, DELTA, 2 )
XC
XC   Convert the binary connect time to character.
XC
X`09CALL SYS$ASCTIM ( DELTA_S, DELTA_C, DELTA, %VAL(0) )
XC
XC   Insert the colon between year & hour, and insert the dash between`20
XC`09day & hour.
XC
X`09ABS_C(12:12) = COLON
X`09DELTA_C(5:5) = DASH
XC
XC   Format the retrun string.
XC
X`09TIMECUR = ABS_C // TAB // DELTA_C
XC
XC   Return.
XC
X`09RETURN
X`09END
$ CALL UNPACK TIMECUR.FOR;1 577170431
$ create 'f'
X`09.TITLE`09TIMEEDIV - Time division routine.
X`09.IDENT`09/01/
X;++
X;   TIMEEDIV.MAR - The function of this routine is to divide a quadword
X;`09by a quadword and return a quadword result and a quadword remainder.
X;
X;
X;   Calling Procedure:
X;
X;`09status = TIMEEDIV( divisor, dividend, result, remainder ) ! FORTRAN
X;
X;   Entry Conditions:
X;
X;`094(AP) - must contain the address of the quadword dividend.
X;`098(AP) - must contain the address of the quadword divisor.
X;
X;   Exit Conditions:
X;
X;`0912(AP) - must contain the address of the quadword to receive the
X;`09`09result.
X;`0916(AP) - must contain the address of the quadword to receive the
X;`09`09remainder.
X;
X;`09R0 - will contain 1 on exit.
X;`09     if divide by 0 then = 0
X;---------------------------------------------------------------------------
V---
X;
X;   Psect for quadword divide.
X;
X`09.PSECT`09TIMEEDIV
X;
XDIVR`09=`094
XDIVD`09=`098
XRESULT`09=`0912
XREMAINDER =`0916
XLOW`09=`090
XHIGH`09=`094
X;
X;   Entry point - TIMEEDIV
X;
X`09.ENTRY`09TIMEEDIV,`5EM<R2,R3,R4,R5,R6,R7,R8,R9>
X;
X;   Fetch the divisor and the dividend.
X;
X`09MOVQ`09@DIVR(AP),R2`09`09; Fetch value of divisor.
X`09MOVQ`09@DIVD(AP),R4`09`09; Fetch value of dividend.
X`09CLRQ`09R6`09`09`09; Clear MS Qw of dividend work area.
X;
X;   Check for divide by zero.
X;
X`09ADDL3`09R2,R3,R0`09`09; If divisor .EQ. 0,
X`09BEQL`09DIVIDE_BY_ZERO`09`09;   then return dividend as result and
X`09`09`09`09`09;   0 for remainder.
X;
X;   Determine the sign of the result and save the value.
X;
X`09XORL3`09R3,R5,R9`09`09; Exclusive OR sign bits of divisor
X`09`09`09`09`09;   and dividend to determine sign
X`09`09`09`09`09;   of result.
X;
X;   Form absolute values of each operand.
X;
X`09TSTL`09R3`09`09`09; Is divisor < 0 ??
X`09BGEQ`0910$`09`09`09;   No
X`09MOVQ`09R2,R0`09`09`09;   Yes; Place divisor in scratch area
X`09CLRQ`09R2`09`09`09;`09 Zero difference area
X`09SUBL`09R0,R2`09`09`09;`09 0 - divisor(low)
X`09SBWC`09R1,R3`09`09`09;`09 0 - divisor(high) - carry
X10$:
X`09TSTL`09R5`09`09`09; Is dividend < 0 ??
X`09BGEQ`0920$`09`09`09;   No
X`09MOVQ`09R4,R0`09`09`09;   Yes; Place dividend in work area
X`09CLRQ`09R4`09`09`09;`09 Zero difference area
X`09SUBL`09R0,R4`09`09`09;`09 0 - dividend(low)
X`09SBWC`09R1,R5`09`09`09;`09 0 - dividend(high) - carry
X20$:
X;;;;
X;
X;
X;   Shift 128 bit dividend work area 1 bit left.
X;;;;
X`09CLRL`09R8`09`09`09; Clear the loop counter.
XLOOP:
X`09ASHQ`09#1,R6,R6`09`09; Shift dividend MS left 1 bit.
X`09BITL`09#`5Ex80000000,R5`09`09; If dividend LS hi bit = 1,
X`09BEQL`0930$`09`09`09;   then
X`09BISL`09#1,R6`09`09`09;     Set MS low bit = 1.
X30$:`09`09`09`09`09; Endif
X`09ASHQ`09#1,R4,R4`09`09; Shift dividend LS left 1 bit.
X;
X;   Trial subtract the divisor from the dividend work area (most significent
V)
X;
X`09MOVQ`09R6,R0`09`09`09; Move the MS dividend work area to tmp
X`09SUBL`09R2,R0`09`09`09; Subtract divisor(low).
X`09SBWC`09R3,R1`09`09`09; Subtract divisor(high) w/carry.
X`09BLSS`0950$`09`09`09; If result is positive, then
X`09MOVQ`09R0,R6`09`09`09;   Place result in dividend MS
X`09BISL`09#1,R4`09`09`09;   Set dividend LS low bit = 1.
X50$:`09`09`09`09`09; Endif
X;
X;   Process the loop control data and repeat loop if not done
X;
X`09AOBLSS`09#64,R8,LOOP
X;;;;
X;   Set the signs of the result and remainder based on the divisor and divid
Vend
X;;;;
X`09TSTL`09@DIVD(AP)`09`09; If dividend < 0,
X`09BGEQ`0970$`09`09`09;   then
X`09MOVQ`09R6,R0`09`09`09;     Place remainder in scratch area
X`09CLRQ`09R6`09`09`09;     Zero remainder storage area.
X`09SUBL`09R0,R6`09`09`09;     0 - remainder(low)
X`09SBWC`09R1,R7`09`09`09;     0 - remainder(high) - carry
X70$:`09`09`09`09`09; Endif
X;
X;   Register 9 has sign to set result to.
X;
X`09TSTL`09R9`09`09`09; If saved sign < 0,
X`09BGEQ`0980$`09`09`09;   then
X`09MOVQ`09R4,R0`09`09`09;     Place result in scratch area.
X`09CLRQ`09R4`09`09`09;     Zero result storage area.
X`09SUBL`09R0,R4`09`09`09;     0 - result(low)
X`09SBWC`09R1,R5`09`09`09;     0 - result(high) - carry
X80$:`09`09`09`09`09; Endif
X;;;;
X;   Store the result and remainder values.
X;;;;
X`09MOVL`09#1,R0`09`09`09; Set the return status.
XDIVIDE_BY_ZERO:
X`09MOVQ`09R4,@RESULT(AP)`09`09; Store the result.
X`09MOVQ`09R6,@REMAINDER(AP)`09; Store the remainder.
X;
X;   Return`20
X;
XEXIT:
X`09RET
X;
X`09.END
$ CALL UNPACK TIMEEDIV.MAR;1 1564323094
$ create 'f'
X`09.TITLE`09TIMEEMUL Extended multiply routine
X`09.IDENT`09/01/
X;++
X;   TIMEEMUL.MAR - The function of this routine is to multiply a quadword`20
X;`09by a quadword and return a quadword result.
X;
X;   Calling Procedure:
X;
X;`09status = TIMEEMUL( multiplier, multiplican, result )`09! FORTRAN
X;
X;   Entry Conditions:
X;
X;`094(AP) - must contain the address of the quadword multiplier.
X;`098(AP) - must contain the address of the quadword multiplican.
X;
X;   Exit Conditions:
X;
X;`0912(AP) - must contain the address of the quadword to receive the
X;`09`09quadword result.
X;
X;`09R0 - will contain 1 on exit.
X;`09     if overflow R0 = 0.
X;---------------------------------------------------------------------------
V---
X;
X;   Psect for quadword multiply.
X;
X`09.PSECT`09TIMEEMUL
X;
XMULC `09=`094
XMULR`09=`098
XRESULT`09=`0912
XLOW`09=`090
XHIGH`09=`094
X;
X;   Entry point - TIMEEMUL
X;
X`09.ENTRY`09TIMEEMUL,`5EM<R2,R3,R4,R5,R6,R7,R8,R9>
X;
X;   Fetch the multiplier and multiplicand.
X;
X`09MOVQ`09@MULR(AP),R2`09`09; Fetch value of multiplier.
X`09MOVQ`09@MULC(AP),R4`09`09; Fetch value of multiplicand.
X`09CLRQ`09R6`09`09`09; Clear LS part of multiplicand area.
X;
X;   Determine the sign of the result and save the value.
X;
X`09XORL3`09R3,R5,R9`09`09; Exclusive OR sign bits of multiplier
X`09`09`09`09`09;   and multiplicand to determine sign
X`09`09`09`09`09;   of result.
X;
X;   Form absolute values of each operand.
X;
X`09TSTL`09R3`09`09`09; Is multiplier < 0 ??
X`09BGEQ`0910$`09`09`09;   No
X`09MOVQ`09R2,R0`09`09`09;   Yes; Place multiplier in scr area
X`09CLRQ`09R2`09`09`09;`09 Zero difference area
X`09SUBL`09R0,R2`09`09`09;`09 0 - multiplier(low)
X`09SBWC`09R1,R3`09`09`09;`09 0 - multiplier(high) - carry
X10$:
X`09TSTL`09R5`09`09`09; Is multiplicand < 0 ??
X`09BGEQ`0920$`09`09`09;   No
X`09MOVQ`09R4,R0`09`09`09;   Yes; Place multiplicand in work area
X`09CLRQ`09R4`09`09`09;`09 Zero difference area
X`09SUBL`09R0,R4`09`09`09;`09 0 - multiplicand(low)
X`09SBWC`09R1,R5`09`09`09;`09 0 - multiplicand(high) - carry
X20$:
X;;;;
X;
X;
X;   Add multiplier and multiplicand then shift multiplicand.
X;;;;
X`09CLRL`09R8`09`09`09; Clear the loop counter.
XLOOP:
X`09BITL`09#1,R4`09`09`09; If multiplicand LS low bit set,
X`09BEQL`0925$`09`09`09;   then
X`09ADDL`09R2,R6`09`09`09;     Add MS multiplicand(low) to`20
X`09`09`09`09`09;       multiplier(low).
X`09ADWC`09R3,R7`09`09`09;     Add MS multiplicand(high) to
X`09`09`09`09`09;       multiplier(high) with carry.
X25$:`09`09`09`09`09; Endif
X;
X;   Shift 128 bit multiplicand work area 1 bit right.
X;
X`09ASHQ`09#<-1>,R4,R4`09`09; Shift LS right 1 bit.
X`09BICL`09#`5Ex80000000,R5`09`09; Clear LS hi bit.
X`09BITL`09#1,R6`09`09`09; If MS low bit = 1,
X`09BEQL`0930$`09`09`09;   then
X`09BISL`09#`5Ex80000000,R5`09`09;     Set LS high bit = 1.
X30$:`09`09`09`09`09; Endif
X`09ASHQ`09#<-1>,R6,R6`09`09; Shift MS right 1 bit.
X`09BICL`09#`5Ex80000000,R7`09`09; Clear MS hi bit.
X;
X;   Process the loop control data and repeat loop if not done
X;
X`09AOBLSS`09#64,R8,LOOP
XEND_LOOP:
X;;;;
X;   Set the signs of the result based on the multiplier and multiplicand.
X;   `09Register 9 has sign to set result to.
X;;;;
X`09TSTL`09R9`09`09`09; If saved sign < 0,
X`09BGEQ`0980$`09`09`09;   then
X`09MOVQ`09R4,R0`09`09`09;     Place result in scratch area.
X`09CLRQ`09R4`09`09`09;     Zero result storage area.
X`09SUBL`09R0,R4`09`09`09;     0 - result(low)
X`09SBWC`09R1,R5`09`09`09;     0 - result(high) - carry
X80$:`09`09`09`09`09; Endif
X;;;;
X;   Check for overflow.
X;;;;
X`09MOVL`09#1,R0`09`09`09; Set the return status = 1
X`09ADDL3`09R6,R7,R1`09`09; If multiplicand MS .ne. 0
X`09BEQL`0990$`09`09`09;   then
X`09MOVL`09#0,R0`09`09`09;     set return status = 0
X90$:`09`09`09`09`09; Endif
X;;;;
X;   Store the result value.
X;;;;
X`09MOVQ`09R4,@RESULT(AP)`09`09; Store the result.
X;
X;   Return`20
X;
XEXIT:
X`09RET
X;
X`09.END
$ CALL UNPACK TIMEEMUL.MAR;1 844888009
$ create 'f'
XC   ------------------------------------------------------------------------
V---
XC   TIMEGET - The function of this routine is to find the next character
XC`09string from the time calculation line and return pointers to the First`2
V0
XC`09and Last characters of the string.
XC
XC`09The delimiters are:
XC
XC`09`09end of string
XC`09`09'('
XC`09`09')'
XC
XC`09Beginning and trailing blanks will not be returned.
XC
XC   ------------------------------------------------------------------------
V---
XC
X`09INTEGER*4 FUNCTION TIMEGET ( STRING, S1, S2 )
XC
X`09IMPLICIT INTEGER*4 (A-Z)
XC
X`09EXTERNAL`09SS$_NORMAL
XC
X`09PARAMETER`09OPEN_P='('
X`09PARAMETER`09CLOSE_P=')'
X`09PARAMETER`09BLANK=' '
XC
X`09CHARACTER`09STRING*(*)
XC
X`09INTEGER*4`09S1, S2, TMP
X`09INTEGER*4`09STRING_S
XC
XC   ------------------------------------------------------------------------
V---
XC
XC   Initialize the return code.
XC
X`09TIMEGET = %LOC(SS$_NORMAL)
XC
XC   Find the beginning of the string.
XC
X`09STRING_S = LEN( STRING )
XC
X`09S1 = S2 + 1
X`09TMP = LIB$SKPC ( BLANK, STRING(S1:STRING_S) ) + (S1-1)
X`09IF ( TMP .EQ. (S1-1) ) THEN
X`09`09TIMEGET = 0
X`09`09GOTO 999
X`09END IF
X`09S1 = TMP
XC
XC   Find the end of the string.
XC
X`09TMP = INDEX( STRING(S1:STRING_S), OPEN_P ) + (S1-1)
X`09IF ( TMP .NE. (S1-1) .AND. TMP .NE. S1 ) THEN
X`09`09S2 = TMP - 1
X`09ELSE
X`09`09TMP = INDEX( STRING(S1:STRING_S), CLOSE_P ) + (S1-1)
X`09`09IF ( TMP .NE. (S1-1) ) THEN
X`09`09`09S2 = TMP
X`09`09ELSE
X`09`09`09S2 = STRING_S
X`09`09ENDIF
X`09ENDIF
XC
XC   Remove trailing blanks from the string.
XC
X`09STATUS = STR$TRIM( STRING(S1:S2), STRING(S1:S2), TMP )
X`09S2 = TMP + (S1-1)
XC
XC   Return
XC
X999`09CONTINUE
X`09RETURN
X`09END
$ CALL UNPACK TIMEGET.FOR;1 578512302
$ create 'f'
XC Last Modified:  14-MAY-1990 20:28:31.66, By: RLB`20
X
X`09INTEGER*4 FUNCTION TIMEKEY( string,bin_val )
XC
X`09IMPLICIT INTEGER*4 (A-Z)
X`09CHARACTER*(*) string
X`09INTEGER*4 bin_val(2)
XC
XC+/TIMEKEY
XC
XC Functional Description:
XC`09Check for absolute time specified by a keyword.  The recognized
XC`09keywords and their meanings are:
XC
XC`09`09YESTERDAY`0900:00 AM of the previous day
XC`09`09TODAY`09`0900:00 AM of the current day
XC`09`09TOMORROW`09midnight of the current day (00:00 AM tomorrow)
XC`09`09THISMONTH`09first day of the current month (00:00 AM)
XC`09`09NEXTMONTH`09first day of the next month (00:00 AM)
XC`09`09LASTMONTH`09first day of the previous month (00:00 AM)
XC`09`09THISYEAR`09January 1st of the current year (00:00 AM)
Xc`09        LASTYEAR`09January 1st of the next year (00:00 AM)
Xc`09        NEXTYEAR`09January 1st of the next year (00:00 AM)
XC`09`09THISWEEK`090000 AM on the last Monday (start of this week)
XC`09`09NEXTWEEK`090000 AM on the next Monday (next week start)
XC`09`09LASTWEEK`090000 AM on the last Monday of a full week
Xc`09`09
XC
XC Input Parameters:
XC`09string - character string compared against the literal keywords.
XC`09`09 Abbreviations are not check for.
XC
XC Implicit Inputs:
XC`09NONE
XC
XC Output Parameters:
XC`09TIMEKEY - returns 1 if keyword match found, else 0.
XC`09bin_val - quadword in which the absolute time is returned.
XC
XC Implicit Outputs:
XC`09NONE
XC
XC Condition Codes Signalled:
XC`09NONE
XC
XC Side Effects:
XC`09NONE
XC
XC-
X`09CHARACTER*24 work
X`09INTEGER*2 work_s
X`09INTEGER*2 tincr(2)
X`09INTEGER*4 days, bin_tmp(2)
X`09INTEGER*4 secs_per_day, ticks_per_sec
X`09PARAMETER (secs_per_day = 24*60*60, ticks_per_sec = 10*1000*1000)
X`09parameter one_day = '1 0:0:0.0'
X`09parameter midnight = '00:00:00.00'
XC
X`09TIMEKEY = 1
X
X`09call sys$bintim(one_day,bin_tmp)
X`09IF (string .EQ. 'YESTERDAY') THEN
XC                                           `20
XC YESTERDAY seen, return absolute time of 00:00 AM yesterday.
XC
X`09    CALL SYS$ASCTIM(work_s, work,, )
X`09    work(13:23) = midnight`09`09!To get 00 AM today
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X`09    CALL lib$sub_times(bin_val, bin_tmp, bin_val)`09!Minus 1 day
X
X`09    ELSE IF (string .EQ. 'TODAY') THEN
XC
XC TODAY seen, return absolute time of 00:00 AM on this day
XC
X`09    CALL SYS$ASCTIM(work_s, work,, )
X`09    work(13:23) = midnight`09`09!To get 00 AM today
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X
X`09    ELSE IF (string .EQ. 'TOMORROW') THEN
XC
XC TOMORROW seen, return absolute time of 00:00 AM tomorrow morning.
XC
X`09    CALL SYS$ASCTIM(work_s, work,, )
X`09    work(13:23) = midnight`09`09!To get 00 AM today
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X`09    CALL lib$add_times(bin_val, bin_tmp, bin_val)`09!plus 1 day
X
X`09    ELSE IF (string .EQ. 'THISMONTH') THEN
XC
XC THISMONTH seen, return absolute time of 00:00 AM on the 1st of the month.
XC
X`09    CALL SYS$ASCTIM(work_s, work,, )
X`09    work(13:23) = midnight`09`09!To get 00 AM today
X`09    work(1:2) = ' 1'`09`09`09!First day of month
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X
X`09    ELSE IF (string .EQ. 'THISYEAR') THEN
XC
XC THISYEAR seen, return absolute time of 00:00 AM on the 1st of January.
XC
X`09    CALL SYS$ASCTIM(work_s, work,, )
X`09    work(13:23) = midnight`09`09!To get 00 AM today
X`09    work(1:6) = ' 1-JAN'`09`09!First day of year
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X
X`09    ELSE IF (string .EQ. 'LASTYEAR') THEN
XC
XC THISYEAR seen, return absolute time of 00:00 AM on the 1st of January.
XC
X`09    CALL SYS$ASCTIM(work_s, work,, )
X`09    work(13:23) = midnight`09`09!To get 00 AM today
X`09    work(1:6) = ' 1-JAN'`09`09!1st day of year
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X`09    call lib$sub_times(bin_val, bin_tmp, bin_val) ! subtract 1 day`20
X`09    call sys$asctim(work_s, work, bin_val, )
X`09    work(1:6) = ' 1-JAN'
X`09    call sys$bintim(work(1:work_s), bin_val)
X
X`09    ELSE IF (string .EQ. 'NEXTYEAR') THEN
XC
XC THISYEAR seen, return absolute time of 00:00 AM on the 1st of January.
XC
X`09    CALL SYS$ASCTIM(work_s, work,, )
X`09    work(13:23) = midnight`09`09!To get 00 AM today
X`09    work(1:6) = '31-DEC'`09`09!last  day of year
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X`09    call lib$add_times(bin_val, bin_tmp, bin_val) ! add 1 day`20
X
X`09    ELSE IF (string .EQ. 'NEXTMONTH') THEN
XC
XC NEXTMONTH seen, return absolute time of 00:00 AM on the 1st of next month.
XC
Xc  get the 1st of this month first
Xc  then compute first of next month
X`09    CALL SYS$ASCTIM(work_s, work,, )
X`09    work(13:23) = midnight`09`09!To get 00 AM today
X`09    work(1:2) = ' 1'`09`09`09!First day of month
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
Xc`09    CALL SYS$GETTIM(bin_val)
X`09    call lib$mult_delta_time(32,bin_tmp)
X`09    CALL lib$add_times(bin_val, bin_tmp, bin_val)
X`09    CALL SYS$ASCTIM(work_s, work, bin_val, )
X`09    work(13:23) = midnight`09`09!To get 00 AM of +32 days
X`09    work(1:2) = ' 1'`09`09`09!First day of next month
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X
X`09    ELSE IF (string .EQ. 'LASTMONTH') THEN
XC
XC LASTMONTH seen, return absolute time of 00:00 AM on the 1st of last month.
XC
Xc  get the 1st of this month first
Xc  then compute first of last month
Xc
X`09    CALL SYS$ASCTIM(work_s, work,, )
X`09    work(13:23) = midnight`09`09!To get 00 AM today
X`09    work(1:2) = ' 1'`09`09`09!First day of month
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
Xc`09    CALL SYS$GETTIM(bin_val)`09`09! Now produce
X`09    CALL lib$sub_times(bin_val, bin_tmp, bin_val) !Minus 1 day
X`09    CALL SYS$ASCTIM(work_s, work, bin_val, )
X`09    work(13:23) = midnight`09`09!To get 00 AM of`20
X`09    work(1:2) = ' 1'`09`09`09!First day of past month
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X
X`09    ELSE IF (string .EQ. 'THISWEEK') THEN
XC
XC THISWEEK seen, return absolute time of 00:00 AM on the latest Monday
XC
X`09    CALL SYS$GETTIM(bin_val)
X`09    CALL LIB$DAY_OF_WEEK( bin_val, days )
X`09    days = days-1
X`09    if( days.gt.0 ) then
X`09      call lib$mult_delta_time(days,bin_tmp)
X`09      CALL lib$sub_times(bin_val, bin_tmp, bin_val)
X`09    endif
X`09    CALL SYS$ASCTIM(work_s, work, bin_val, )
X`09    work(13:23) = midnight`09`09!To get 00 AM on Monday
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X
X`09    ELSE IF (string .EQ. 'NEXTWEEK') THEN
XC
XC NEXTWEEK seen, return absolute time of 00:00 AM on the next Monday
XC
X`09    CALL SYS$GETTIM(bin_val)
X`09    CALL LIB$DAY(days, bin_val)
X`09    days = 7 - MOD( MOD(days, 7) + 2, 7)
X`09    call lib$mult_delta_time(days,bin_tmp)
X`09    CALL lib$add_times(bin_val, bin_tmp, bin_val)
X`09    CALL SYS$ASCTIM(work_s, work, bin_val, )
X`09    work(13:23) = midnight`09`09!To get 00 AM on Monday
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X
X`09    ELSE IF (string .EQ. 'LASTWEEK') THEN
XC
XC LASTWEEK seen, return absolute time of 00:00 AM on the past Monday
XC
X`09    CALL SYS$GETTIM(bin_val)
X`09    CALL LIB$DAY(days, bin_val)
X`09    days = 7 + MOD( MOD(days, 7) + 2, 7)
X`09    call lib$mult_delta_time(days,bin_tmp)
X`09    CALL lib$sub_times(bin_val, bin_tmp, bin_val)
X`09    CALL SYS$ASCTIM(work_s, work, bin_val, )
X`09    work(13:23) = midnight`09`09!To get 00 AM on Monday
X`09    CALL SYS$BINTIM(work(1:work_s), bin_val)
X`09    ELSE
XC
XC Not a keyword!
XC
X`09    TIMEKEY = 0
X`09    ENDIF
XC
X
X`09RETURN
X`09END
$ CALL UNPACK TIMEKEY.FOR;1 1295927103
$ create 'f'
X.TITLE`09TIME_MESSAGES`09TIME messages and condition codes
X.FACILITY`09TIME,2047/PREFIX=TIME__
X!
X! Messages for TIME program.  Following the defacto standard on the Fermilab
X! Accelerator VAX's, the facility number used with a program's built-in
X! messages is 2047 (shared among many, many programs).
X!
X! Modification History:
X! V1.0`0915-Mar-83`09FJN`09Created
X!
X
X.SEVERITY`09ERROR
XINVABSTIM`09<invalid absolute time format>
XINVADD`09`09<invalid add>
XINVCMP`09`09<invalid compare>
XINVDELTIM`09<invalid delta time format>
XINVDIV`09`09<invalid divide>
XINVINT`09`09<invalid integer value format>
XINVMUL`09`09<invalid multiply>
XINVOPR`09`09<invalid operation>
XINVSUB`09`09<invalid subtract>
XMISPAR`09`09<time parameter missing>
XOVRFLO`09`09<time calculation overflow>
XTOOMNYOPR`09<too many operands supplied>
X
X.END
$ CALL UNPACK TIME_MESSAGES.MSG;1 1195077451
$ v=f$verify(v)
$ EXIT
Technical Details
Message-ID: <8045354@MVB.SAIC.COM>
Path: arc1-ca.pugleaf.net!sparky!uunet!usc!news.service.uci.edu!unogate!mvb.saic.com!vmsnet-sources

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!usc!news.service.uci.edu!unogate!mvb.saic.com!vmsnet-sources
From: ewilts@galaxy.gov.bc.ca (Ed Wilts)
Newsgroups: vmsnet.sources
Subject: Time functions, part 02/02
Message-ID: <8045354@MVB.SAIC.COM>
Date: Fri, 04 Sep 1992 05:22:33 GMT
Reply-To: EWILTS@GALAXY.GOV.BC.CA
Organization: BC Systems Corporation
Lines: 1204
Approved: Mark.Berryman@Mvb.Saic.Com