Mike, Thanks for the routine. Will give it a try.
Mike -----Original Message----- From: The IBM z/VM Operating System [mailto:ib...@listserv.uark.edu] On Behalf Of Mike Walter Sent: September 24, 2009 12:31 PM To: IBMVM@LISTSERV.UARK.EDU Subject: Re: Date/Time functions for REXX program? The CSL routines for date/time conversions can be a bit... uh, how do I say this kindly... unintuitive - and complex. Perhaps the TIMEDIFF EXEC pasted below might help out in an easier fashion. I'd have been utterly lost writing it without the help of Doug Breneman. Mike /* Prolog; See Epilog for additional information ******************** * Exec Name - TIMEDIFF EXEC * * Unit Support - IS * * Status - Version 2, Release 2.0 * ********************************************************************/ address 'COMMAND' parse source xos xct xfn xft xfm xcmd xenvir . parse upper arg parms 1 operands '(' options ')' parmrest ?function=(xct='FUNCTION') If parms='?' | parms='' then Signal Explain NUMERIC DIGITS 13 If ?function then Do operands=arg(1) options =arg(2) End parse upper var operands date1 time1 date2 time2 outfmt . upper options ?days =wordpos('DAYS', options)>0 ?met =wordpos('MET', options)>0 ?term =wordpos('TERM', options)>0 ?lifo =wordpos('LIFO', options)>0 ?fifo =wordpos('FIFO', options)>0 | , wordpos('STACK',options)>0 If ?days & ?met then Do say xfn'; mutually exclusive options: DAYS, MET' Call Exit 20 '?' End If ?function & (?lifo+?fifo+?term)>0 then Do say xfn'; TERM, LIFO, FIFO, & STACK options are' , 'invalid for rexx function calls.' say 'For more help, enter:' xfn '?' Return /* w/o anything to cause a function call error */ End If time1='' then Do say xfn'; missing first time, second date, second time.' Call Exit 20 '?' End If date2='' then Do say xfn'; missing second date, second time.' Call Exit 20 '?' End If time2='' then Do say xfn'; missing second time.' Call Exit 20 '?' End datenow=date('S') timenow=time() If date1='*' then date1=datenow If time1='*' then time1=timenow If date2='*' then date2=datenow If time2='*' then time2=timenow If date2='=' then date2=date1 If time2='=' then time2=time1 days=0;hh=00; mm=00; ss=00 If date1=date2 & time1=time2 then Signal Reply /* Implied Exit */ date1fmt=DetermineDateFmt(date1) date2fmt=DetermineDateFmt(date2) window_position = '-50' Call APILOAD 'VMREXMTR' Call APILOAD 'VMREXTMR' If date1fmt='vm_tmr_format_rexx_date_s' then Do parse var time1 hh':'mm':'ss time1=hh||mm||ss minuend_stamp = date1||time1 End Else minuend_stamp = date1 time1 minuend_stamp_length = 'LENGTH'(minuend_stamp) minuend_stamp_format = 'VALUE'(date1fmt) minuend_stamp_bias = 0 minuend_stamp_window_type = vm_tmr_window_sliding minuend_stamp_window_position = window_position If date2fmt='vm_tmr_format_rexx_date_s' then Do parse var time2 hh':'mm':'ss time2=hh||mm||ss subtrahend_stamp = date2||time2 End Else subtrahend_stamp = date2 time2 subtrahend_stamp_length = 'LENGTH'(subtrahend_stamp) subtrahend_stamp_format = 'VALUE'(date2fmt) subtrahend_stamp_bias = 0 /* no bias */ subtrahend_stamp_window_type = vm_tmr_window_sliding subtrahend_stamp_window_position = window_position If outfmt='' then outfmt='vm_tmr_format_met' diff_stamp_format = 'VALUE'(outfmt) diff_stamp_buffer_size = '30' /* Was 32 */ diff_stamp_bias = '0' diff_stamp_window_type = vm_tmr_window_sliding diff_stamp_window_position = window_position dtsargs='DateTimeSubtract retcode reascode' , 'minuend_stamp' , 'minuend_stamp_length' , 'minuend_stamp_format' , 'minuend_stamp_bias' , 'minuend_stamp_window_type' , 'minuend_stamp_window_position' , 'subtrahend_stamp' , 'subtrahend_stamp_length' , 'subtrahend_stamp_format' , 'subtrahend_stamp_bias' , 'subtrahend_stamp_window_type' , 'subtrahend_stamp_window_position' , 'diff_stamp_buffer' , 'diff_stamp_buffer_size' , 'diff_stamp_length' , 'diff_stamp_format' , 'diff_stamp_bias' , 'diff_stamp_window_type' , 'diff_stamp_window_position' Call 'CSL' dtsargs If reascode=307 then Do say xfn'; Invalid first date or time entered:' date1 time1 Call Exit 20 '?' End If reascode=308 then Do say xfn'; Invalid second date or time entered:' date2 time2 Call Exit 20 '?' End If retcode<>0 then say xfn'; retcode='retcode parse var retcode l3retcode 4 parmerr If l3retcode='-27' then say 'Possible error in DateTimeSubtract CSL argument:' , word(dtsargs,parmerr) If reascode<>0 then say xfn'; reasoncode='reascode If retcode<>0 then Call Exit retcode parse var diff_stamp_buffer days'/'hh':'mm':'ss'.'millisec . days=abs(days) dayhrs=days*24 If \?days & \?met then hh=dayhrs+hh days=abs(days) hh=right(abs(hh), max(length(hh),2) ,0) mm=right(abs(mm), 2 ,0 ) ss=right(abs(ss), 2 ,0 ) Signal Reply /* Implied Exit, Do not change to "Call"! */ Call Exit 0 DetermineDateFmt: parse arg date Ldate=length(date) ?numeric=( verify(date,'0123456789')=0 ) parse var date 1 . 3 C3date 4 . 5 C5date , 6 C6date 7 . 8 C8date 9 . , 1 . 2 C345date 6 . , 1 L2date 3 Select When Ldate=5 & ?numeric then Return 'vm_tmr_format_rexx_date_j' When Ldate=7 & ?numeric then Return 'vm_tmr_format_rexx_date_j_long' When Ldate=8 & ?numeric then Return 'vm_tmr_format_rexx_date_s' When Ldate=10 & C5date='/' & C8date ='/' then Return 'vm_tmr_format_csl' When Ldate=10 & C5date='-' & C8date='-' then Return 'vm_tmr_format_iso' When Ldate=10 & C5date='-' & C8date='-' then Return 'vm_tmr_format_iso' When Ldate=8 & C3date='/' & C6date='/' then Return 'vm_tmr_format_rexx_date_u' Otherwise Do say xfn'; unsupported date format for date:' date Call Exit 20 '?' End End Return /* Doc only */ /* ******************************************************************* */ /* * SUB - ROUTINES * */ /* ******************************************************************* */ Exit: parse arg exitrc todo If todo='?' then say 'For more help, enter:' xfn '?' If verify(exitrc,'-0123456789')>0 then Exit 999999 If ?function & exitrc>0 then Do say xfn 'arguments: "'parms'"' Return /* without anything to cause a function call error */ End Exit exitrc Reply: /* Be careful to always "SIGNAL REPLY" or ?function will fail*/ If days='DAYS' | days='' then days=0 Select When ?function & ?met then Return days'/'hh':'mm':'ss When ?function & ?days then Return days hh':'mm':'ss When ?function then Return hh':'mm':'ss When ?fifo & ?met then queue '*' days'/'hh mm ss When ?fifo & ?days then queue '*' days hh mm ss When ?fifo then queue '*' hh mm ss When ?lifo & ?met then push '*' days'/'hh mm ss When ?lifo & ?days then push '*' days hh mm ss When ?lifo then push '*' hh mm ss /* Display at console */ When ?met then say days'/'hh':'mm':'ss When ?days then say days hh':'mm':'ss Otherwise say hh':'mm':'ss End Call Exit 0 Explain: 'PIPE (NAME TimeDiffExplain)' , '| <' xfn xft xfm , '| INSIDE ANYCASE /ExplainBegin/ /ExplainEnd/' , '| CONSOLE' Call Exit 4 /* ExplainBegin: TIMEDIFF provides the number of hours, minutes and seconds (and optionally, days) between two pairs of dates and times. The command format is: >>-TIMEDIFF-+-date1------+--+-time1----+--+-date2------+--+-time2----+-> +-yyyy-mm-dd-+ +-hh:mm:ss-+ +-yyyy-mm-dd-+ +-hh:mm:ss-+ +-yyyy/mm/dd-+ +-hhmmss---+ +-yyyy/mm/dd-+ +-hhmmss---+ +-yyyymmdd---+ +-*--------+ +-yyyymmdd---+ +-*--------+ +-yyyyddd----+ +-yyyyddd----+ +-=--------+ +-yyddd------+ +-yyddd------+ +-mm/dd/yy---+ +-mm/dd/yy---+ +-*----------+ +-*----------+ +-=----------+ >-----------+-------------------------------+------------------------->< +--(----| Options |---+-----+---+ +--)--+ Options: +-TERM--+ |--+------+--+-------+-------------------------------------------------| +-DAYS-+ +-FIFO--+ +-MET--+ +-STACK-+ +-LIFO--+ Dates are supported between 01 Jan 0001 AD and 31 Dec 9999 AD. The dates may be entered as any of the following date formats: Format Format type ---------- ---------------------------------- * - Current date yyyy-mm-dd - ISOdate yyyy/mm/dd - DateTimeSubtract CSL yyyymmdd - Standard date; rexx date(S) yyyyddd - Julian date; (long) yyddd - Julian date; rexx date(J) mm/dd/yy - Gregorian Date; rexx date(U) = - For 'date2' only, equal to 'date1' The times may be entered as any of the following time formats: Format Format type ---------- ---------------------------------- * - Current time hh:mm:ss - Specific time hhmmss - Specific time = - For 'time2' only, equal to 'time1' Options: DAYS - Display the number of days between the dates For a 'TERM' display as: Time difference is: n days, n hours, n minutes, n seconds. For a function call as: days hh:mm:ss For LIFO, FIFO, or STACK: * n n n n MET - Display the days in "Mission Elapsed Time" format. For a 'TERM' display as: Time difference is: n days/ n hours, n minutes, n seconds. For a function call as: days/hh:mm:ss For LIFO, FIFO, or STACK: * days/hh:mm:ss TERM - Display results at console (DEFAULT) FIFO - Queue results in Program Stack STACK - Queue results in Program Stack LIFO - Push results in Program Stack Usage notes: 1) Options for a rexx function call are entered after a comma, as in: diff=timediff(date1 time1 date2 time2,options) 2) Any date entered as a 2-digit year (Gregorian or Julian) will be converted to a 4-digit year using a 50 year sliding window from the the current date. The sliding window range of years is computed as: current year -50, through current year +49. The century is taken from the matching year in that range. Examples: 2-digit Resulting Current year; Window begin; Window end; year 4-digit year ------------- ------------ ---------- ------- ------------ 2000 2000-50=1950 2000+49=2049 00 2000 49 2049 50 1950 99 1999 2005 2005-50=1955 2005+49=2054 00 2000 49 1949 50 2050 99 1999 Examples from within a REXX program: runtime=timediff('20001231 01:00:00 20001231 02:00:00') diff=timediff('20001231 01:00:00 20001231 02:00:00','MET') say timediff('01/11/00 01:00:00 2000-01-11 02:00:00') say timediff('05/11/50 14:00:00 2000/05/11 14:00:00','DAYS') 'EXEC TIMEDIFF 12/05/84 08:30:00 1999/12/05 = (DAYS' ExplainEnd: */ /* Epilog *********************************************************** * Function - Provide hours, minutes and seconds difference * * between two times. Years between 1942 and * * 2041 supported. * * Component of - N/A * * Command format- See Explain routine above. * * * * Called by - Anyone. * * Dependencies - CSL calls. * * Program Lang. - CMS REXX * * Date Written - 07/11/86 * * Author - Mike Walter, Art Payne * * - Most of the CSL setup was provided courtesy of * * P.D. Breneman (Doug) from IBM. * * Changed | By | Change Description * * ---------+----+---+--------------------------------------------- * * 01/22/90 mrw - Original version * * 20000106 mrw - Update for Y2K, V2.1 (change to CSL call). * * 20000107 mrw - Correct support for ISO dates. * * 20000111 mrw - Add examples to Explain subroutine. * * 20020124 mrw - Make hh, mm, ss= 00 when both dates/times equal. * * 20090501 mrw - In "Exit:" add 'todo' code, when rc<>0 and * * ?function call, display args and Return w/o args * * * ********************************************************************/ "Horlick, Michael" <michael.horl...@cgi.com> Sent by: "The IBM z/VM Operating System" <IBMVM@LISTSERV.UARK.EDU> 09/24/2009 10:10 AM Please respond to "The IBM z/VM Operating System" <IBMVM@LISTSERV.UARK.EDU> To IBMVM@LISTSERV.UARK.EDU cc Subject Date/Time functions for REXX program? Greetings, Would like a few suggestions for a small REXX program I?m writing. I would like to determine the date and time since a user is logged on. I can do a ?CP IND USER userid EXP? and get the CTIME as the number of days, hours, minutes and seconds that user is logged on, which is good, but I would like to determine the actual day, hour, minute and second. For example, right now my EXEC displays the following: xxxxxxx has been logged on for 1 day(s) 7 hour(s) 1 minute(s) 1 second(s). If it is, say 11:30:00 AM right now, I would like it to say additionally ?since Wednesday, September 22 at 4:28:59AM?. Gets a bit complicated, I guess, for year changes, leap years, etc? Also, I would like to determine the amount of time between the current time and a date in the future (our next scheduled VSE IPL, for example) I plan to do the same for the VM IPL time derived from the ?CP Q CPLEVEL? command. Any suggestions would be appreciated. Thanks, Mike The information contained in this e-mail and any accompanying documents may contain information that is confidential or otherwise protected from disclosure. If you are not the intended recipient of this message, or if this message has been addressed to you in error, please immediately alert the sender by reply e-mail and then delete this message, including any attachments. Any dissemination, distribution or other use of the contents of this message by anyone other than the intended recipient is strictly prohibited. All messages sent to and from this e-mail address may be monitored as permitted by applicable law and regulations to ensure compliance with our internal policies and to protect our business. E-mails are not secure and cannot be guaranteed to be error free as they can be intercepted, amended, lost or destroyed, or contain viruses. You are deemed to have accepted these risks if you communicate with us by e-mail.