I agree with Roger. If you HAVE to support older Date conversion
routines, it's much safer to make them front ends for the new CMS
routines. I'd like to add that the REXX date() routine now supports
date conversions.
HOWEVER: The DATECONV stage only does DATE conversion, not DATETIME
conversion. At least some of what was asked for last week was TODSTAMP
-> DATE & TIME, and you can only do that with DateTimeSubtract(DMSDTS).
(The DATECONV stage calls DMSDTS. I hope REXX date() does too.)
In order to use DATECONV on older CMS, you have to install the new
DMSDTS, as well. Directions are on the Web page
<http://pucc.princeton.edu/~pipeline/cslcnsid.html>.
You can do this as far back as CMS 9.
There are a lot of bugs in the CMS 13 date() and DMSDTS. I don't know
if these have all been APARed. A reason to move to CMS 14. You also
need PTFs to the REXX Compiler, if you use that.
I went back to my TOD2TIME and TIME2TOD routines that I posted on
VMSHARE and found a bug in them. I'm not sure what to do about that --
I haven't figured out how to move files to or from VMSHARE, now that I
cannot use dial up. And I haven't yet recoded TOD2TIME/TIME2TOD to use
DMSDTS. (Part of my Y2K project.)
Here's the bug:
say tod2time(000000000000000)
1900/01/01 -7:00:00.000000
This should be:
1899/12/31 17:00:00.000000
The -7 indicates I'm running in Pacific Daylight Time. Your answer will
depend on you time zone. People in time zones >= 0 won't have this
problem. The problem here is that the REXX % and // operators don't
work like the mathematical quotient and remainder when applied to
negative numbers. In math, the remainder is always >= 0, in REXX, the
remainder has the same sign as the dividend. This has bit me several
times now.
Moral: Always test the endpoints!
>Date: Mon, 1 Jun 1998 18:28:20 CDT
>From: Roger Deschner <U52...@UICVM.UIC.EDU>
>Subject: Date Conversions of Every Kind
>To: VME...@UAFSYSB.UARK.EDU
>
>There have been several threads recently about sundry date conversions.
>
><soapbox>
>As we approach the Year 2000 Calamity, it is time to get serious about
>this. Everybody, EVERYBODY, on VM, should start using the IBM-supplied
>PIPE DATECONVERT or its underlying CSL DateTimeSubtract for all date
>conversions. If you are not running CMS14 yet or even (especially) if you
>might never run CMS14, then obtain everything necessary from Princeton.
>It all runs on all CMS versions as old as CMS9, so you can even use it in
>those infamous applications stuck in real 370-mode. If you are using
>CMS13+, use the extended Rexx DATE function. It all works. It's not the
>prettiest thing you ever saw, or the fastest, but it's been subjected to
>extensive testing, and it PRODUCES CORRECT ANSWERS. It WILL work for
>dates after 2000. If it breaks, you can APAR it, or if you are running a
>copy from Princeton, you can get a friend on CMS14 to APAR it because it
>is the same code.
>
>Don't use anything else, ever, again. I won't. Throw away those hundreds
>of buggy old routines (such as the ones on this list last week) without
>even worrying about testing them for this or that Y2K, leap year, 2047,
>2036, 2100, or whatever well known date bug. Just throw them all away,
>and embrace CORRECT ANSWERS, with PIPE DATECONVERT!
></soapbox>
>
>Roger Deschner University of Illinois at Chicago rog...@uic.edu
>Aliases: u52...@uicvm.uic.edu
Alan Ackerman, Bank of America, 925-675-4358, usbo...@ibmmail.com
*** Note new area code -------> ***
Here is an exec I use. I also have ISODATE REXX, written by the piper
and locally enhanced that may also be handy.
/*
DATEI
Rexx function to create an ISO date.
'DATEI'() returns current date as yyyy-mm-dd.
Also accepts 2 args which are the same as the 2nd & 3rd args to date().
*/
false = (1=0)
true = (1=1)
Address COMMAND
Trace O
select
when arg() = 0
then date = date('S')
when arg() = 1
then date = date('S', arg(1))
when arg() = 2
then date = date('S', arg(1), arg(2))
otherwise
do
say 'DATEI Error, too many args.'
return 'Error'
end
end
return substr(date,1,4) || '-' || substr(date,5,2) || '-' || substr(date,7,2)
/*
Name..........: ISODATE REXX
Author........: John Hartmann a.k.a. The father of PIPES
Date..........: 17 Nov 1993 18:08:24
Purpose.......: Convert STATE timestamp to ISO form
Notes.........: The new CMS isodate option is a better solution
usage
pipe listfile (date | isodate | . . .
sorted pipe listfile (date | isodate sort | . . .
descending pipe listfile (date | isodate sort desc | . . .
Dependencies..: MM/DD/YY date format
Revisions.....: 4/11/96 BAF added sort option
1/13/93 BAF updated for Y2K compliance
*/
ARG OPT ord .
Signal on novalue
If opt = 'SORT'
then optstage = '| sort 57-70' ord
else optstage = ''
'callpipe (endchar ? name ISODATE)',
'|*:',
'|spec 1.56 1 /19/ n 63.2 n 57.2 n 60.2 n 66.2 n 69.2 n 72.2 n',
'|xlate 57-* blank 0', /* add leading zeros to Month & Hours*/
'|a: pick 59.2 >>= /56/', /* test year for rolling date window */
'|b: faninany',
optstage, /* optionally sort */
'|*:',
'?',
' a:',
'| specs 1-* 1 /20/ 57', /* y2k */
'| b:'
exit RC
--
Rich Greenberg Work: PM0RMG atsign WSPVM1.worldspan.com +1 770-563-6656
N6LRT Marietta, GA, USA Play: richgr atsign netcom.com +1 770-321-6507
Eastern time. I speak for myself & my dogs only. VM'er since CP-67
Canines:Val(Chinook,CGC,TT),Red(Husky,(RIP)),Shasta(Husky,TT) Owner:Chinook-L
On Wed, 3 Jun 1998 10:19:27 +0100
"Withall, Keith" <Keith....@swi.galileo.com> wrote:
>Has anyone else found it a shame that the REXX Date function will not
>produce a date in the ISODATE format. I have a routine that checks to
>see what files have changed on a disk and uses LISTFILE with the ISODATE
>option to get a sortable list by date. I then want to compare it with
>the date that I last looked to see what has changed. I have to
>manipulate a REXX date to make it look like an ISODATE for the
>comparison.
>
>Is there anything in any of the newer releases of CMS. We are on CMS13.
>
>Keith
As long as we're discussing REXX DATE() formats ...
It strikes me that there are repeated requests for REXX DATE() function
output conversion are never quite met by the DATE() function. Would it
make sense for REXX DATE() to add support a specific syntax, where one
could request specify the output date format exactly as they want it
(where the non-M, D, Y, W characters are used as the output delimiters).
In the following examples, uppercase letters would be entered unchanged,
(although they could be entered as lowercase -- I'm just using upper
to clarify constants from variables) and lowercase substituted with
valid dates.
In it's simplest form, just conversion between formats:
1) the first argument is the actual input date needing conversion
or if it contains alpha characters 'M', 'D', 'Y', 'W' and there are
no other arguments, use todays' date to display in the given format.
2) the second argument tells REXX the date format (in a new, flexible
human format) of the given date in the first argument
3) the third argument is the desired output format in that same
new human format)
4) an optional mathematical argument to be applied to the input date
before conversion to the output format.
Command Output
------------------- ------------------------------
say date('MM/DD/YY') Today's date in mm/dd/yy fmt
say date('MM.DD.YY') Today's date in mm.dd.yy fmt
say date('YY/MM/DD') Today's date in yy/mm/dd fmt
say date('YYYY-MM-DD') Today's date in yyyy-mm-dd fmt
say date('YYYYxMMxDD') Today's date in yyyyxmmxdd fmt
such as 1998x06x03
say date('MM/DD/YY.DDD') Today's date in a combined
Gregorian/Julian fmt such as
06/03/98.154
say date('WWW') Left 3 of Today's weekday= Wed
say date('WWWW') {and so on, w/more W's} Left 4 of Today's weekday= Weds
Adding onto that could be conversion of dates (help me here, I'm on
ESA 121, and I think there's already syntax for this sort of thing):
say date('mm/dd/yy','MM/DD/YY','WWW')
Would translate the input date,
of the specified format,
and display the left three
letters of that weekday.
e.g.
say date('05/11/50','MM/DD/YY','WWW') Would display 'Thu'
say date('yyyy-mm-dd','YYYY-MM-DD','MM/DD/YY','-nnnn')
Would subtract nnnn days from
the input date, in the given
format, and display the
result in the requested
mm/dd/yy fmt
say date('mm/dd/yy','MM/DD/YY','YYYY-MM-DD','+nnnn')
Would add nnnn days to the
input date and display the
result in the requested
yyyy-mm-dd fmt
say date('O','O','WWWW','+30') Would add 30 days to today's
date and display the left four
letters of that weekday.
say date('O','O','WWWW','/2') Would divide today's date in
half, and display the left four
letters of that weekday. No,
I don't know what multiply and
divide would be used for yet,
either. Someone clever will.
For cases where you know the input date format, but are unsure of
the delimiter character due to various inputs (e.g. 1998-06-03 and
1998/06/03) perhaps one could enter:
say date(somevariable,'YYYY%MM%DD','YY.DDD')
Would convert the input date
where you know where the fields
are, but the delimiter may
change, and dislplay it in the
requested YY.DDD format.
This gets IBM out of the business of specifying date formats (Sorted,
Normal, European, Usa, Ordered, etc.) while permitting the customer
flexibility in defining using DATE() to match the format of the date
their applications use, even to the point of allowing single wild-card
characters for delimiters between year, month, and day.
The date addition and subtraction capability lends itself quite handily
to solving the need to specify the same date two ways in tape label
processing (i.e. we all have to add some number of days to the current
date and get the results in cyyddd or yyddd for the EXDTE option on
LABELDEF -- pity labeldef doesn't accept RETPD and convert the date
itself!).
A penny for your thoughts...
Mike Walter
Hewitt Associates LLC
I vastly prefer:
isodate = translate('1234-56-78',date('S'),'12345678')
fulldate = translate('56/78/1234',date('S'),'12345678')
These are (a) easier to see at a glance what you're doing, and
(b) somewhat shorter (and faster, perhaps).
I find it harder to see and verify the '8's in Perry's version than to
just use the actual / or - that you want in the output.
I also don't like the UNIXish use of 0 for the first character.
Another possibility is:
isodate = translate('year-mn-dt',date('S'),'yearmndt')
fulldate = translate('mn/dt/year',date('S'),'yearmndt')
It's all a matter of taste, chacun (?) a son gout, de gustibus non
est diputandem, and all that.
>Date: Wed, 3 Jun 1998 11:29:55 CDT
>From: Roger Deschner <U52...@UICVM.UIC.EDU>
>Subject: Re: Date Conversions of Every Kind
>
>> Has anyone else found it a shame that the REXX Date function will not
>> produce a date in the ISODATE format. I have a routine that checks to
>> see what files have changed on a disk and uses LISTFILE with the ISODAT
>> option to get a sortable list by date. I then want to compare it with
>> the date that I last looked to see what has changed. I have to
>> manipulate a REXX date to make it look like an ISODATE for the
>> comparison.
>>
>> Is there anything in any of the newer releases of CMS. We are on CMS13.
>>
>> Keith
>>
>> Technical Specialist - VM
>> Galileo International
>> Internal 2957
>> External +44 1793 888957
>> FAX +44 1793 886504
>> IBMMAIL Address GBRCFH3F
>> Internet Address Keith....@Swi.Galileo.com
>
>They could, but it's Soooooo easy. The following two are thanks to Perry
>Reuter - store them in your bag of tricks:
>
> isodate = translate('0123845867',date('S')'-','012345678')
> fulldate = translate('4586780123',date('S')'/','012345678')
>
>These are so simple, that while I would agree it is a shame, I think the
>requirement could be satisfied by simply adding Perry's little tricks to
>the documentation. This works on all versions of Rexx - even on other
>platforms.
>
>We have to be careful unilaterally extending Rexx, because it is not
>exclusively ours anymore. Long ago, Rexx joined the realm of universal
>languages like Fortran and Cobol. It has its own standards committee, in
>which IBM VM Endicott is but one participant. I personally run Rexx on
>two up-to-date VM systems, two obsolete VM systems, three Unixen, OS/2,
>and three Microsoft platforms - because I am unable to deal with a
>Rexx-less computer. (or an Xedit-less computer, for that matter) As a
>result, if CMS Rexx DATE() were extended to offer Isodate output, I would
>ignore it and continue to use Perry's TRANSLATE technique. There's a
>separate Rexx newsgroup/listserv list where I am certain they debate
>these kinds of things with at least as much vigor as we debate LOGON
>HERE.
>
>Roger Deschner University of Illinois at Chicago rog...@uic.edu
>Aliases: u52...@uicvm.uic.edu
>=============== 2000-01-01: Field Day for Murphy's Law =================
You might check out the EDate function on VMShare, here is a brief
section
taken from the comments at the top of the routine:
EDATE is an extension of the REXX builtin DATE function.
It allows specification of an optional date parameter (within 0001-
9999) as well as date computation by addition or subtraction.
There is no correction for the switchover to Gregorian calendar.
Examples:
x = edate() /* returns todays date with format */
/* (dd Mmm yyyy). Same as date().
*/
x = edate(j,'08/07/85')/* returns the julian equivalent of
*/
/* 08/07/85 which is 85219
*/
x = edate(w,00001,1) /* returns the name of the day of
*/
/* week which is one day past Jan 1
*/
/* 1900 which is Tuesday.
*/
x = edate(s,,'- //1',l)/* returns one year before today's
*/
/* date in sorted (long) format
which*/
/* is (for example) 1985/09/25.
*/
> Mike Walter
> Hewitt Associates LLC
Michael Motek
Senior Programmer/Analyst
University of Victoria