TIA.
James R. Evans
Systems Support - MVS
----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to LIST...@VM.MARIST.EDU with the message: INFO TSO-REXX
results:
date('b') time('n')=733513 12:09:35
***
--
Mark Zelden
Sr. Software and Systems Architect - z/OS Team Lead
Zurich North America / Farmers Insurance Group - ZFUS G-ITO
mailto:mark....@zurichna.com
z/OS Systems Programming expert at
http://expertanswercenter.techtarget.com/
Mark's MVS Utilities: http://home.flash.net/~mzelden/mvsutil.html
"Evans, James R. (RET-DAY)" <James...@REEDELSEVIER.COM>
Sent by: TSO REXX Discussion List <TSO-...@VM.MARIST.EDU>
04/17/2009 11:05 AM
Please respond to
TSO REXX Discussion List <TSO-...@VM.MARIST.EDU>
Subject
REXX friendly STCK conversion
Is there a kind soul on this list who can point me to a REXX friendly
TIA.
James R. Evans
Systems Support - MVS
******************* PLEASE NOTE *******************
This E-Mail/telefax message and any documents accompanying this
transmission may contain privileged and/or confidential information and is
intended solely for the addressee(s) named above. If you are not the
intended addressee/recipient, you are hereby notified that any use of,
disclosure, copying, distribution, or reliance on the contents of this
E-Mail/telefax information is strictly prohibited and may result in legal
action against you. Please reply to the sender advising of the error in
transmission and immediately delete/destroy the message and any
accompanying documents. Thank you.
bobh
-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf
> Date: Fri, 17 Apr 2009 12:05:44 -0400
> From: James...@REEDELSEVIER.COM
> Subject: [TSO-REXX] REXX friendly STCK conversion
> To: TSO-...@VM.MARIST.EDU
>
> Is there a kind soul on this list who can point me to a REXX friendly
> STCK conversion utility, please?? In an ideal world, I'd like to invoke
> a function with an 8 byte STCK value and get the DATE('B') and the
> TIME('N') in return. Does such a tool exist??
>
James,
Here's one I picked up ca. 1994, authored by Tony Rall.
Mark Wheeler
http://www.linkedin.com/in/marklwheeler
/* REXX--------------------------------------------------------------*/
/* Function: Convert a /370 STCK (SToreClocK) value */
/* (base 1900/01/01) into local date and time. */
/* */
/* History: When- Who----- What--------------------- */
/* 1.00 11/07/86 TRALL Created by Tony Rall */
/* 1.01 05/26/94 MYRC99 replaced 27-line DOW with 1-line, */
/* allow embedded blanks on input, */
/* cosmetic reformatting of output, */
/* more output (inc. YYYYDDD), */
/* callable as FUNCTION w/ std result. */
/* Dependencies: MVS or VM (unless "TZO(hh)" is specified.) */
/*-------------------------------------------------------------------*/
/***********************************************************************\
| from REXXHOW FORUM at 01:48:17 on 94/01/13 GMT (by TRALL at ALMVSA) |
| Here's an exec I call STCKTIME. It requires the "store clock" time to|
| be passed as an argument. Feel free to incorporate it in any exec. |
| Sample execution (note that the precision of the output is related to |
| how many (supposedly significant) digits you provide as input): |
| STCKTIME a94455 tzo(-8) ===> 1994/05/12 15:45:00 Thursday |
| STCKTIME a9445512345 ===> 1994/05/12 15:46:42.0269 Thursday |
| STCKTIME 00000000 tzo(0) ===> 1900/01/01 00:00:00 Monday |
| STCKTIME ffffffff tzo(0) ===> 2042/09/17 23:53:46 Wednesday |
| |
| If invoked from a function-call <xx=STCKTIME(yy)>, the returned |
| data will be exactly in the form: yyyy/mm/dd hh:mm:ss.dddddd |
| |
\***********************************************************************/
Parse Source opsys howcalled full_exec_name .
Parse Upper Value REVERSE(full_exec_name) With exec_name '\'
Parse Upper Value REVERSE( exec_name) With exec_name '.'
Parse Upper Arg clock 'T' -0 parms
clock = SPACE(clock,0) /* skrunch out all blanks */
fc? = (howcalled \= 'COMMAND') /* 1 = Function or Subroutine */
help = \DATATYPE(clock,'X') | LENGTH(clock)<6
tzo = ''
parse_good=1 /* Assume parse will succeed. */
Do i=1 To WORDS(parms) /* Scan all parms. */
Parse Value WORD(parms,i) With parm '(' value ')' .
Select
When ABBREV('HELP',parm,1) Then help = 1
When ABBREV('TZO' ,parm,1) & DATATYPE(value,'N') Then tzo = value
Otherwise
If \fc? Then Say 'Unknown parameter ('WORD(parms,i)').'
parse_good=0
End
End
If \parse_good Then help=1
If help Then Do
Say ' '
Say " "exec_name" clock <TZO()>"
Say ""
Say " Convert a /370 STCK value to local date and time. Assumed to"
Say " be executed on an MVS or VM system with the same GMT offset as"
Say ' the specified clock value, unless "TZO(hh)" is supplied.'
Say ' If "TZO(hh)" IS specified, program is OpSys-independent.'
Say ""
Say "clock The STCK (Store Clock) value in hex. At least 6 digits"
Say " are required (to approach accuracy to the nearest minute)."
Say " Extra digits provide additional accuracy."
Say ''
Say "TZO(hh) The offset from GMT (in hours). Positive is east of"
Say " Greenwich; negative is west. If omitted, the offset"
Select
When opsys = 'TSO' Then m1 = 'is obtained from TSO control blocks'
When opsys = 'CMS' Then m1 = 'is obtained from CP control blocks'
Otherwise m1 = 'defaults to "-6" (CST)'
End
Say ' ' m1'.'
Say ''
Say ' For example, "STCKTIME A94455 TZO(-8)" '
Say ' will generate "1994/05/12 15:45:00 Thursday" '
Say ''
Exit
End
/*
Get the GMT offset from local time. Only works if system has correct
GMT offset.
*/
Select
When DATATYPE(tzo,'N') Then
tzo = tzo*3600 /* cvt caller's HOURS to SECs */
When opsys = 'TSO' Then Do /* Get from MVS CVT. */
cvt = C2X(STORAGE(10,4)) /* Get CVT pointer. */
cvttz_p = D2X(X2D(cvt) + X2D(130)) /* Get pointer to CVTTZ. */
tzo = STORAGE(cvttz_p,4) /* Get TZ offset (CVTTZ). */
tzo = C2D(tzo,4)*1.048576 /* Diff from GMT in seconds. */
End
When opsys = 'CMS' Then Do /* Get from VM. */
Parse Value DIAG(0) With 33 tzv +4 . /* Time Zone data from system.*/
tzo = C2D(tzv,4) /* Diff from GMT in seconds. */
End
Otherwise Do
tzo = -6 * 3600 /* assume CST (Z-6) */
If \fc? Then Say 'No GMT_Offset found in' opsys ,
'or specified by caller. Assuming' tzo/3600 'hours.'
End
End
tzo = (tzo+.5)%1 /* and round to an integer. */
/*
Compute number of digits to be used in computation.
*/
ndigits = MAX(6,1.2*LENGTH(clock)+1)%1 /* 1.2 dec digits/hex digit. */
Numeric Digits ndigits
/*
Convert the clock value to GMT seconds since 1900/01/01.
*/
m2 = clock '=' /* start the output msg */
clock = X2D(clock)*1.048576 / 16**(LENGTH(clock)-8)
clock = clock + tzo /* LOCAL seconds since 1900 */
If clock < 0 Then Parse Value 0 0 ,
With clock tzo /* Clock cannot be MINUS. */
seconds = clock // (24*60*60) /* Get seconds since midnite */
days = clock % (24*60*60) /* Get days since 1900. */
days = days + 2415021 /* Get Julian days. */
Parse Value DATECONV(days) With y m d dow /* Convert to normal form. */
hours = RIGHT( seconds %3600 ,2,' ') /* Convert time-of-day. */
minutes = RIGHT((seconds//3600)%60,2,'0')
seconds = TRANSLATE(FORMAT(seconds//60,2),'0',' ')
m1 = hours':'minutes':'seconds 'on' dow',' y'/'m'/'d
tzoh = FORMAT(tzo/3600,,1)/1
If tzoh \<0 Then tzoh = '+'tzoh
t1 = y'/'m'/'d hours':'minutes':'seconds
t2 = y'/'m'/'d RIGHT(hours/1,2,'0')':'minutes':' || ,
TRANSLATE(FORMAT(seconds,2,6),'0',' ')
If fc? Then Exit t2
Say '--->' m2 t1 dow
Say '--->' opsys ' JD='days ,
' BD='days-1721426 ,
' 370D='days-2415021 ,
' MVS='S2MVS(y m d) ,
'Z'tzoh
Exit /*================================================================*/
DATECONV: Procedure
/*
Convert (astronomical) Julian day number into month, day, and year.
*/
Parse Upper Arg julday
j =julday-1721119 /* Reference day 1 to 0000/03/01 */
d =((4*j-1)//146097+146097)//146097 /* 146097=days in 400 years */
d =d%4 /* Approx day within 100 years */
y =(4*j-1)%146097*100+(4*d+3)%1461 /* Compute year. */
d =(((4*d+3)//1461+1461)//1461+4)%4 /* Day within year (3/1 = 1) */
m =(5*d-3)%153 /* Month number, March=0. */
d =(((5*d-3)//153+153)//153+5)%5 /* Day within month. */
If m<10 , /* What month are we in? */
Then Parse Value m+3 With m /* March-December */
Else Parse Value m-9 y+1 With m y /* January-February */
dow = (julday+1)//7 /* from JulDate, get DayOfWeek */
Return RIGHT(y,4,'0') RIGHT(m,2,'0') RIGHT(d,2,'0') ,
WORD('Sun Mon Tues Wednes Thurs Fri Satur',1+dow) || 'day'
S2MVS: Procedure
Parse Arg yyyy mm dd
Return RIGHT(yyyy,4,'0') || ,
RIGHT(3055*(mm+2)%100-(mm+10)%13*2-91 ,
+ (1-((yyyy//4)+3)%4+((yyyy//100)+99)%100 ,
- ((yyyy//400)+399)%400)*(mm+10)%13+dd ,3,'0')
/*--------------------end of STCKTIME.EXEC-----------------------------*/
_________________________________________________________________
Rediscover HotmailĀ®: Get quick friend updates right in your inbox.
http://windowslive.com/RediscoverHotmail?ocid=TXT_TAGLM_WL_HM_Rediscover_Updates2_042009
> Date: Fri, 17 Apr 2009 12:05:44 -0400
> From: James...@REEDELSEVIER.COM
> Subject: [TSO-REXX] REXX friendly STCK conversion
> To: TSO-...@VM.MARIST.EDU
>
> Is there a kind soul on this list who can point me to a REXX friendly
> STCK conversion utility, please?? In an ideal world, I'd like to invoke
> a function with an 8 byte STCK value and get the DATE('B') and the
> TIME('N') in return. Does such a tool exist??
James,
I (re)discovered one I wrote myself. %-)
Mark Wheeler
http://www.linkedin.com/in/marklwheeler
/* TOD2CLCK EXEC
REXX function to convert TOD to external clock time.
Format: TOD2CLCK(tod,datefmt,offset)
Where:
tod is a value from the TOD clock
See IBM System 370 XA Principles of Operation for
explanation of format.
datefmt is the format of the output date field.
Default: 'S'.
See HELP REXX DATE for permissible values.
offset is offset (in hours) from GMT (ex. CDT = -5.0).
Default: 0.
Author: Mark Wheeler
Date: 8 Sep 2003
*/
arg tod, datefmt, offset
if datefmt = '' then
datefmt = 'S'
if offset = '' then
microseconds_offset = 0
else
microseconds_offset = offset * 3600000000 /* Microseconds per hour */
numeric digits 16
tod_l = length(tod)
select
when datatype(tod,'X'),
& tod_l = 16 then
tod_b = x2b(tod)
when datatype(tod,'B'),
& tod_l >= 52,
& tod_l <= 64 then
tod_b = tod
when tod_l = 8 then
tod_b = c2b(tod)
otherwise
return /* Invalid value of "tod" */
end
tod_d = b2d(left(tod_b,52)) + microseconds_offset
days_since_19000101 = tod_d % 86400000000 /* Microsecs per day */
days_since_00000101 = days_since_19000101 + 693595
date = date(datefmt,days_since_00000101,'B')
microsecs_since_midnight = tod_d // 86400000000
secs_since_midnight = microsecs_since_midnight / 1000000
hh = right( secs_since_midnight % 3600 ,2,0)
mm = right( secs_since_midnight % 60 // 60 ,2,0)
ss = right(format(secs_since_midnight // 60 ,,6),9,0)
time = hh':'mm':'ss
return date time
_________________________________________________________________
Windows Liveā¢: Life without walls.
http://windowslive.com/explore?ocid=TXT_TAGLM_WL_allup_1b_explore_042009
> /* REXX */
> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
> /* */
> /* This EXEC uses the IPCS BLSUXTOD service to convert timer */
> /* units. */
> /* */
> /* Examples: */
> /* 9DD86997FE000000 --> 12/30/1987 09:49:21.046528 */
> /* 9DDA6997FE000000 --> 01/01/1988 00:00:00.000000 */
> /* B72F6997FE000000 --> 02/13/2002 22:30:06.632960 */
> /* */
> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
> Arg TUNITS
> TUNITS = X2c(TUNITS)
> TIMESTAMP = Copies(0,26) /* force result length=26 */
> Address linkpgm "BLSUXTOD TUNITS TIMESTAMP"
> Say TIMESTAMP
>
Is BLSUXTOD well-documented anywhere?
In: 10.7 "z/OS V1R10.0 MVS IPCS Customization"
I read:
1. Input -- a binary TOD or STCKE value
They aren't the same, are they?
I tried it, with small changes for user-friendliness. The
output value appears to be windowed between 1971 and 2114.
Is this well-documented anywhere?
I tried it with a value from: Figure 10-45 of
z/Architecture
Principles of Operation
SA22-7832-07
....
user@MVS:166$ tod AEE3 EFA4 02F4 0000
07/01/1997 00:00:21.000000
Twenty-one seconds? Ugh! Is this behavior well-documented
anywhere?
Would STCKCONV do any better?
-- gil
> Does the ADDRESS need 'MVS'
> ??
>
Abolutely not. I think we can test Mark Z. to test his stuff.
It works as coded within the limits of the underlying BLSUXTOD.
For examples of similar usage, see SYS1.SAMPLIB(CSFTEST), et. al.
> -----Original Message-----
> From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On
> Behalf
> Of Mark Zelden
> Sent: Friday, April 17, 2009 11:22 AM
> ...
> Address linkpgm "BLSUXTOD TUNITS TIMESTAMP"
-- gil
"In the clock value, bit 0 is treated as on to allow the
service to handle values from May 11, 1971, at
11:56:53.685248 to January 25, 2114, at 11:50:41.055743. In
the value, the partial microseconds must be truncated and
not rounded."
I can't answer all the questions about documentation or lack of, that is
for
IBM.
Maybe you'll like this one better. :-) It's what I used before I found
out
about BLSUXTOD.
/* REXX */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* This EXEC accepts a string which represents the clock in */
/* timer units since January 1, 1900. It converts the string */
/* to decimal equivalent and then performs calculations to */
/* determine the corresponding Julian date and the time of */
/* day. This output will be displayed on the terminal unless */
/* the STACK option is specified after the input value. In */
/* that case, the value will be placed on the stack, to be */
/* read by a calling EXEC. */
/* */
/* Examples: */
/* 9DD86997FE000000 --> 1987.364 9:49:21.046 */
/* 9DDA6997FE000000 --> 1988.001 0:00:00.000 */
/* B72F6997FE000000 --> 2002.044 22:30:06.632 */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Parse Upper Arg timestring parms
If Wordpos('DEBUG',parms) > 0 Then Trace 'Intermediates'
If Wordpos('TRACE',parms) > 0 Then Trace 'Intermediates'
If \Datatype(timestring,'X') Then,
Do; Say 'Invalid data ('timestring') - contains other',
'than hexadecimal characters.'
Exit 21; End
Numeric Digits 18
timestring = Left(timestring,13,0)
work = X2D(timestring)
work = work % 1000
fraction = work // 1000; work = work % 1000
seconds = work // 60; work = work % 60
minutes = work // 60; work = work % 60
hours = work // 24; work = work % 24
days = work - 29218 /* Subtract out 1900-1979 */
year = 1980
Do While days > 0
current = 365 + (year = 4 * (year%4))
If days > current Then year = year + 1
days = days - current
End
days = days + current
output = year'.'Right(days,3,0) hours':' || ,
Right(minutes,2,0)':' ||,
Right(seconds,2,0)'.' ||,
Right(fraction,3,0)
If Wordpos('STACK',parms) > 0,
Then Push output
Else Say output
Exit
--
Mark Zelden
Sr. Software and Systems Architect - z/OS Team Lead
Zurich North America / Farmers Insurance Group - ZFUS G-ITO
mailto:mark....@zurichna.com Office:847-605-6570 Cell:630-306-8166
z/OS Systems Programming expert at
http://expertanswercenter.techtarget.com/
Mark's MVS Utilities: http://home.flash.net/~mzelden/mvsutil.html
Paul Gilmartin <PaulGB...@AIM.COM>
Sent by: TSO REXX Discussion List <TSO-...@VM.MARIST.EDU>
04/17/2009 12:07 PM
Please respond to
TSO REXX Discussion List <TSO-...@VM.MARIST.EDU>
Subject
Re: REXX friendly STCK conversion
On Apr 17, 2009, at 10:21, Mark Zelden wrote:
07/01/1997 00:00:21.000000
-- gil
******************* PLEASE NOTE *******************
This E-Mail/telefax message and any documents accompanying this
transmission may contain privileged and/or confidential information and is
intended solely for the addressee(s) named above. If you are not the
intended addressee/recipient, you are hereby notified that any use of,
disclosure, copying, distribution, or reliance on the contents of this
E-Mail/telefax information is strictly prohibited and may result in legal
action against you. Please reply to the sender advising of the error in
transmission and immediately delete/destroy the message and any
accompanying documents. Thank you.
----------------------------------------------------------------------