From: bruce@ais.com (Bruce C. Wright)
Newsgroups: comp.os.vms
Subject: Re: Implimenting "TOMORROW +1: 0:0" from an .EXE
Date: 12 Jan 93 12:32:23 GMT
Organization: Applied Information Systems, Chapel Hill, NC

In article <11JAN199319201213@spades.aces.com>, gavron@spades.aces.com (Ehud Gavron 602-570-2000 x. 2546) writes:
> In article <1993Jan11.153438.28624@magnus.acs.ohio-state.edu>, pat@magnus.acs.ohio-state.edu (Patrick E Plaisted) writes...
> #I have the need to set an AST timer queue entry to fire at, in DCL
> #syntax, "TOMORROW +1:0:0".  I've looked through all the LIB$ routines,
> #as well as $bintim and $asctim.  Is there a simple way to get a
> #quadword time value set to this so I can stick it into $setimr?  
> #My only thoughts on how to do this are:   
> # 
> #  1. calculate the number of hours to midnight.
> #  2. calculate the number of minutes to midnight.
> #  3. calculate the number of seconds to midnight.
> #  4. use lib$cvt_to_internal_time to convert these values to
> #     delta time quadwords.
> #  5. use lib$add_times to add these values to a quadword containing the 
> #     current time.
> #  6. again using lib$add_times, add 1 hour to this value.
> #  7. finally, call $setimr with the quadword.
> # 
> #I think this approach should work, but am I missing something really 
> #obvious?  Is there an easier way to do this?
> 
> 	1. Call SYS$GETTIM to get current time in ticks (10ns units)
> 	2. Add 144,000,000 to this number 
> 	   24 hrs x 60 min  x 60 sec  x 100000 ns    144,000,000 ns/day
> 	   	      -----     -----         ---- =
> 		       hr        min          sec
> 	3. Use SYS$ASCTIM to get this in ascii format in the form
> 	   DD-MMM-YYYY HH:MM:SS.hh
> 
> 	4. Insert in the 13th position of the string "01:00:00.00"
> 	5. Call SYS$BINTIM
> 
> 	(I may be off on the number in #2 but it looks right.  I'm
> 	 sure someone will rush to correct me if it isn't.)

Sorry, Ehud.  It isn't.  The number you compute (144,000,000) is only
equivalent to 14.4 seconds :).  You only multiplied in one of the 60's
and used the wrong multiplier to convert from seconds to 100's of
nanoseconds (which should be 10,000,000, not 100,000).  The correct
number is 864,000,000,000.  Naturally this won't fit into a longword;
the largest time that can is about 7 minutes as I recall.  You'll want
to use the quadword math routines to do it in a reasonably easy-to-read
way (and you'll have to for the addition to the system binary time as
well).

Alternatively, you could take advantage of the fact that the VMS time
starts at midnight on 17-NOV-1858, so that midnight always falls on
values that are modulo 864,000,000,000 (I believe VMS ignores the leap
seconds that are sometimes inserted, although this wouldn't matter for
most applications), and compute the time as follows:

	1.  Get the current time using $gettim.  (Or, to compute the
	    offset from a specific time, convert a string with that
	    time using $bintim).
	2.  Add 864,000,000,000 to the current time.
	3.  Compute the remainder of this value with 864,000,000,000.
	4.  Subtract the remainder from the value computed in step 2.
	5.  Add the number of 100's of nanoseconds in one hour to the
	    result computed in step 4.  (This number can be computed
	    as 60*60*10,000,000, or 36,000,000,000;  as noted above
	    all of these steps will require quadword math).
	6.  If you want the result in a printable format, feed this
	    number to $asctim.

This avoids multiple conversions to and from string (printable) format,
but I'm not sure that it's any nicer than the first algorithm presented.
It would be convenient if one of the VMS libraries or system services
allowed such a specification to be given to some $bintim-like routine,
but I'm unaware of any such service if it exists.

Bruce C. Wright