Whew, that "DateTimeSubtract" can be confusing and awkward to use. That
led me to the TIMEDIFF EXEC pasted below.
Mike Walter
Hewitt Associates
The opinions expressed herein are mine alone, not my employer's.
/* 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 *
* *
********************************************************************/
"Quay, Jonathan (IHG)" <[email protected]>
Sent by: "The IBM z/VM Operating System" <[email protected]>
07/26/2010 10:48 AM
Please respond to
"The IBM z/VM Operating System" <[email protected]>
To
[email protected]
cc
Subject
Re: zVM Performance Toolkit: Can I record/report CPU by userid using 10
minutes interval?
Also take a look at using a Rexx routine to compute time differences using
the CMS Multitasking
CSL call "DateTimeSubtract". See z/VM CMS Application Multitasking for
your release of VM for formats and identifiers.
From: The IBM z/VM Operating System [mailto:[email protected]] On
Behalf Of Kris Buelens
Sent: Monday, July 26, 2010 11:19 AM
To: [email protected]
Subject: Re: zVM Performance Toolkit: Can I record/report CPU by userid
using 10 minutes interval?
Converting the time:
DateConv 5.8 TODABS REXXS Timeout'
2010/7/26 Michel Beaulieu <[email protected]>
Good Day,
Thanks for the feedback from both of you.
You gave me useful tips that I can act upon.
This week I will experiment with the following approach:
The settings will be changed to have extended summary data saved
to "systemid FCXSUMMnn" on a 10 minutes interval.
I will copy and rename these files regularly on another minidisk.
That will become some kind of extended archive.
I want to stay away from processing raw monitor data as much as possible.
Later I will be able to get other fields information besides CPU seconds
currently.
Then, I will see what I can extract using REXX and/or PIPELINE
to extract information from 'FC41' records (by userid) and 'FC42' records
(by user class).
I already have the REXX code to convert simple floating point fields.
(C2F).
I will have to find or create some code to convert the TOD field. (That
should not be too hard)
I will keep you and this list informed on my progress.
Regards,
Michel Beaulieu
Montreal, Canada
|*|
Date: Mon, 26 Jul 2010 07:18:09 -0500
From: [email protected]
Subject: Re: zVM Performance Toolkit: Can I record/report CPU by userid
using 10 minutes interval?
To: [email protected]
I do this simply with VMUTIL, using PIPE VMC pipeid CPU | STEM FCX100. ?
Frank M. Ramaekers Jr.
From: The IBM z/VM Operating System [mailto:[email protected]] On
Behalf Of Michel Beaulieu
Sent: Friday, July 23, 2010 2:47 PM
To: [email protected]
Subject: zVM Performance Toolkit: Can I record/report CPU by userid using
10 minutes interval?
Good day,
I am trying to do something that seems to me a good challenge to do with
z/VM performance toolkit.
The end result that I want to have is a set of records for a selected
number of userids.
Each record would be for a 10 minutes interval.
format:
yyyymmdd hhmm userid cpusec
That means I would create 24 x 6 = 144 records per day per virtual
machine.
Accumulating that over many months, I can load that data in my favorite
spreadsheet
and do all kind of numerical analysis.
I am trying to use z/VM Performance Toolkit to help me to do that and I am
stuck!
The best I could do was to use plotvar with trend files.
However, that is too much aggregated for my need.
I welcome your suggestions.
Michel Beaulieu
Montreal, Canada
_____________________________________________________ This message
contains information which is privileged and confidential and is solely
for the use of the intended recipient. If you are not the intended
recipient, be aware that any review, disclosure, copying, distribution, or
use of the contents of this message is strictly prohibited. If you have
received this in error, please destroy it immediately and notify us at
[email protected].
--
Kris Buelens,
IBM Belgium, VM customer support
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.