There are 17 leap days from 1900 to 1970, not 16. Just write them out starting 
at 1904, 1908... and count them.

That would make the results one day later than they should be.

The microseconds value should be 2208988800000000, which in hex is 
7d91048bca000, and after shifting that 12 bits to the right you get hex 
7d91048bca000000, the same value in the example in the manual.

One way to test is to use hex 8126D60E46000000 as an input STCK value. The 
Principles of Operation says that is January 1 1972, in the leap seconds table 
before the first leap second. The Unix value for that date is 63072000.

Other than that, the code is a nice improvement. Thanks for posting.

Bill

On Thu, 20 Jul 2017 16:10:07 -0400, Tony Harminc wrote:

>On 20 July 2017 at 13:11, Kirk Wolf <[email protected]> wrote:
>
>> I'm actually writing this in Java (to 64-bit java "long" epoch seconds,
>> from both STCK and STCKE inputs), but the sample IBM assembler code
>> initially puzzled me.
>
>I must admit I remain confused by both the sample code and its comments.
>The the notion of "seconds per tod unit" is an odd one. This is a very
>small number (about 0.000000000244140625), and it makes little sense to be
>dividing anything by it. And certainly the constant EPOCST DC X'7A120000'
>isn't it.
>
>This is code I wrote in 1999 to do this. I must also admit I had not
>considered that the Unix representation was signed, and so it doubtless
>produces incorrect output for input dates between 2038 and 2042. But of
>course any code does so by definition, so it's a matter of which failure
>mode you prefer.
>
>I like to think this is easy to read and understand. I think of the
>algorithm this way:
>
>Convert the TOD value into microseconds since Jan 1 1900. Why? Because it's
>trivial and fast, it well fits the architected definition of the TOD clock
>(bit 51 - 1 uS), and it guarantees that this intermediate value does not
>have its high bit on.
>
>Subtract the (constant) difference in microseconds between Jan 1 1900 and
>Jan 1 1970. I hand calculated this by thinking (70 years * 365 days/year =
>25550 days, + (70/4)-1 [-1 because 1900 was not a leap year] = 16 leap days
>) = 25566 days ) * 1440 min/day *60 seconds/minute = 2208902400 seconds *
>1000000 = 2208902400000000 microseconds. I hope I was right...
>
>So here's my old code:
>         STCK  WORK_DWORD
>         LM    R14,R15,WORK_DWORD  TOD CLOCK UNITS
>         SRDL  R14,12            MICROSECONDS SINCE JAN 1, 1900
>         SL    R15,=FL8'2208902400000000'+4 - RIGHT HALF
>         BC    11,*+6            BRANCH ON NO BORROW
>         BCTR  R14,R0             -1 FOR BORROW
>         SL    R14,=FL8'2208902400000000' - LEFT HALF
>         D     R14,=F'1000000'    SECONDS SINCE JAN 1, 1970
>
>As others have pointed out, using the 32-bit registers and checking for
>borrow would be strange for code written in 2017, but of course it still
>works. Using a G register with the appropriate G Load, Shift, and Subtract
>would eliminate 3 instructions.
>
>> - good assembler programmer
>> - XLC/C++ compiler
>> - IBM sample code in a manual
>> - bad assembler programmer
>
>Heh - a colleague is writing his first ever, very simple, TSO command. The
>"IBM sample code in a manual" has meant it's taken him about a week more
>than it should've.
>
>Tony H.

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

Reply via email to