the year 4000 problem
Author Message
the year 4000 problem

sorry if this has been posted here before.  It was forwarded to me from my boss.

For those of you who would like  to work ahead a little:

For the Julian calendar, in use until recent centuries, the rule
was simply

"years divisible by 4, and only such years, are leap years."

However, this made the average length of the calendar year slightly longer
than the solar year (I'm not sure if the latter term is the right one to use
here, but you know what I mean); in other words, under the Julian system,
too many years were being designated as leap years.  And by the late 16th
century, the calendar was reading 10 days behind what it should have; e.g.,
maybe the calendar was reading March 4 when the actual position of the earth
in its orbit about the sun would have called for March 14.

In papal countries, after skipping 10 days in October 1582 to get
back on track (i.e., the day after Oct. 5, 1582 was decreed to be Oct. 16,
as I recollect), the Gregorian calendar thinned out the leap years a bit, in
order to produce a shorter calendar year on average, one that kept up with
the earth's movement about the sun.  (Protestant countries adopted the new
calendar only somewhat later, by the way.)  Its rules are

1) years divisible by 400 ARE leap years (so, for example,
2000 will indeed be a leap year),

2) years divisible by 100 but not by 400 are NOT leap years
(so, for example, 1700, 1800, and 1900 were NOT leap years, NOR will 2100 be
a leap year),

3) years divisible by 4 but not by 100 ARE leap years (e.g.,
1988, 1992, 1996),

4) years not divisible by 4 are NOT leap years.

The only difference, then, between the Julian system and the Gregorian
system (besides the 10-day catchup) is that in the latter system, century
years like 1700, 1800, 1900 are NOT leap years.  (In both calendars, the
extra day in a leap year is always February 29, by the way.)

The Gregorian calendar keeps excellent time, but it could even
better (i.e., very, very excellent) if years like 4000, 8000, etc., were NOT
leap years.  Therefore, it has been proposed that the rules be changed to

0) years divisible by 4000 are NOT leap years,

1') years divisible by 400 but not by 4000 ARE leap years
(so, for example, 2000 will still be a leap year),

2), 3), and 4) as above.

We have a long, long time to decide on this possible change.  Whatever the
ultimate decision, let's hope we don't have a "year 4000 problem"!!!

--
Like everyone who is not in love, he imagined that one chooses the person one loves after endless deliberation and on the strength of diverse qualities and advantages.
- Proust

Wed, 16 Aug 2000 03:00:00 GMT
the year 4000 problem

John Casten wrote something that could (according to me) be resumed as:

01  aYear.
03  cc  pic 99.
03  yy  pic 99.
01  leapSwitch  pic X.
88  leap   value "Y".
88  noLeap value "N".
01  pq  SV9.

if yy = zero
then
divide cc by 4 giving pq
else
divide yy by 4 giving pq
end-if
if px = zero
then
set leap   to true
else
set noLeap to true
end-if

and proposed to extend this for the still present mismatch with the solar year. But John,

Every now and then you can read in your newspaper that the atomic clocks are put 1 second forth (or was it behind?) to accommodate this. So no other leap adjustments are
needed to get the calandar SYNCHRONIZED with the real world.

[Or would you propose to introduce a leapsecondcheck behind each ACCEPT FROM TIME :)) ]

Gr,
Huib

Fri, 18 Aug 2000 03:00:00 GMT
the year 4000 problem

There actually was a brief (VERY brief) discussion at ANSI about whether or not we needed to allow a value of "60" in the second
portion of CURRENT-DATE.  I am afraid that any COBOL program that is running at exactly the time that a leap second is added AND is
running on a system that will return that second and using the intrinsic function for the time, will get the wrong answer.

--
+ +
+   Bill Klein -
"C" is a nice letter to START the name of your programming language with
but I wouldn't want to end up there.

Quote:

>John Casten wrote something that could (according to me) be resumed as:

>01  aYear.
>    03  cc  pic 99.
>    03  yy  pic 99.
>01  leapSwitch  pic X.
>    88  leap   value "Y".
>    88  noLeap value "N".
>01  pq  SV9.

>if yy = zero
>then
>  divide cc by 4 giving pq
>else
>  divide yy by 4 giving pq
>end-if
>if px = zero
>then
>  set leap   to true
>else
>  set noLeap to true
>end-if

>and proposed to extend this for the still present mismatch with the solar year. But John,

>Every now and then you can read in your newspaper that the atomic clocks are put 1 second forth (or was it behind?) to accommodate

this. So no other leap adjustments are

- Show quoted text -

Quote:
>needed to get the calandar SYNCHRONIZED with the real world.

>[Or would you propose to introduce a leapsecondcheck behind each ACCEPT FROM TIME :)) ]

>Gr,
>Huib

Fri, 18 Aug 2000 03:00:00 GMT
the year 4000 problem

I knew it, I knew it! Each and every possibility, however small, is considered by the standards comittee to get the best language in
the universe!

:)) Huib.

Quote:

> There actually was a brief (VERY brief) discussion at ANSI about whether or not we needed to allow a value of "60" in the second
> portion of CURRENT-DATE.  I am afraid that any COBOL program that is running at exactly the time that a leap second is added AND is
> running on a system that will return that second and using the intrinsic function for the time, will get the wrong answer.

Question: should I believe this or is he making fun?

;)

Fri, 18 Aug 2000 03:00:00 GMT
the year 4000 problem

Quote:

> John Casten wrote something that could (according to me) be resumed as:

> 01  aYear.
>     03  cc  pic 99.
>     03  yy  pic 99.
> 01  leapSwitch  pic X.
>     88  leap   value "Y".
>     88  noLeap value "N".
> 01  pq  SV9.

> if yy = zero
> then
>   divide cc by 4 giving pq
> else
>   divide yy by 4 giving pq
> end-if

I think you want to use the remainder here.

Quote:
> if px = zero
> then
>   set leap   to true
> else
>   set noLeap to true
> end-if

Consider this:

01  aYear.
03  cc  pic 99.
03  yy  pic 99.
77  pq  pic 9.
88  leap   value 0.

if yy zero
move function mod(cc, 4) to pq
else
move function mod(yy, 4) to pq
end-if

To test:

if leap
if not leap

PS- Try not to think too system specifically.  On many architectures,
adding a sign when it is not needed, or using an 01 when a 77 will
do is a waste.
--
Judson McClendon          This is a faithful saying and worthy of all
Sun Valley Systems        acceptance, that Christ Jesus came into the

(please remove zzz from email id to respond)

Fri, 18 Aug 2000 03:00:00 GMT
the year 4000 problem

I quote fully this time, to prevent misunderstanding. Comments are inserted.

Quote:

> > John Casten wrote something that could (according to me) be resumed as:

> > 01  aYear.
> >     03  cc  pic 99.
> >     03  yy  pic 99.
> > 01  leapSwitch  pic X.
> >     88  leap   value "Y".
> >     88  noLeap value "N".
> > 01  pq  SV9.

> > if yy = zero
> > then
> >   divide cc by 4 giving pq
> > else
> >   divide yy by 4 giving pq
> > end-if

> I think you want to use the remainder here.

> > if px = zero

You probably  made a typing error? px or pq?

Quote:
> > then
> >   set leap   to true
> > else
> >   set noLeap to true
> > end-if

I do NOT want to use the remainder option here. Dividing an integer number by
4 yields a real number with a decimal part of either .00 or .25 or .50 or
.75. The giving puts the first digit of this decimal part in pq, truncating
the second digit and anything befor the decimal point. So the possible
results in pq are either .0 or .2 or .5 or .7. The check on zero so tests
very accurately on leapness!BTW, pq is my abbreviation for "partial
quotient".

Quote:

> Consider this:

>   01  aYear.
>       03  cc  pic 99.
>       03  yy  pic 99.
>   77  pq  pic 9.
>       88  leap   value 0.

On this I agree. I could have put he condition name (88 level) right under
pq. Like this:01  leapSwitch  pic X.

01  pq  SV9.
88  leap   value zero.
88  noLeap values .2, .5, .7.

Quote:
>   if yy zero
>     move function mod(cc, 4) to pq
>   else
>     move function mod(yy, 4) to pq
>   end-if

Hey! that works, but fells costly (in cpu cycles) to me. Besides, my solution
works in older versions, even before COBOL '68, I think.

Quote:
> To test:

>   if leap
>   if not leap

Hmm... I think it would indeed be better if I had used just one (positively
phrased) condition name in stead of two. My "noLeap" is not necessary and
makes even possible to use "not noLeap". Judson made a good point here.

Quote:
> PS- Try not to think too system specifically.  On many architectures,
>     adding a sign when it is not needed, or using an 01 when a 77 will
>     do is a waste.

I admit tha adding the sign was a Pavlov reflex. I started on big blues!
Adding a sign there as NO waste, but betters performance (no OR-immediates).
Using 77 i.s.o 01 I never considered.

Judson, let's join forces. Your unbeatable! :)

Huib, the Cobol Frog

Sat, 19 Aug 2000 03:00:00 GMT
the year 4000 problem

Quote:

> > > 01  aYear.
> > >     03  cc  pic 99.
> > >     03  yy  pic 99.
> > > 01  leapSwitch  pic X.
> > >     88  leap   value "Y".
> > >     88  noLeap value "N".
> > > 01  pq  SV9.

> > > if yy = zero
> > > then
> > >   divide cc by 4 giving pq
> > > else
> > >   divide yy by 4 giving pq
> > > end-if

> > I think you want to use the remainder here.

> > > if px = zero

> You probably  made a typing error? px or pq?

Actually, it was your error which I didn't catch.  It is copied verbatim from
your original message.  ;-)

- Show quoted text -

Quote:
> > > then
> > >   set leap   to true
> > > else
> > >   set noLeap to true
> > > end-if

> I do NOT want to use the remainder option here. Dividing an integer number
> by 4 yields a real number with a decimal part of either .00 or .25 or .50 or
> .75. The giving puts the first digit of this decimal part in pq, truncating
> the second digit and anything befor the decimal point. So the possible
> results in pq are either .0 or .2 or .5 or .7. The check on zero so tests
> very accurately on leapness!BTW, pq is my abbreviation for "partial
> quotient".

> > Consider this:

> >   01  aYear.
> >       03  cc  pic 99.
> >       03  yy  pic 99.
> >   77  pq  pic 9.
> >       88  leap   value 0.

> On this I agree. I could have put he condition name (88 level) right under
> pq. Like this:01  leapSwitch  pic X.

> 01  pq  SV9.
>     88  leap   value zero.
>     88  noLeap values .2, .5, .7.

> >   if yy zero
> >     move function mod(cc, 4) to pq
> >   else
> >     move function mod(yy, 4) to pq
> >   end-if

> Hey! that works, but fells costly (in cpu cycles) to me. Besides, my solution
> works in older versions, even before COBOL '68, I think.

The COBOL compiler will almost certainly generate a divide to an intermediate
field, and move the result into the receiving field.  Almost any machine
language divide is going to also provide the remainder as well.  It is as easy
for the compiler to move the remainder to the result as to move the quotient to
the result.  On some architectures, a MOD operator might be even more efficient.
If the compiler generates efficient inline code for FUNCTION MOD, there should
be no difference in the memory or CPU cycles.  It is also far more intuitive to
understand than your clever approach.  I did a very similar thing in a PL/I
course back in the 70's, and the instructor never did understand how the
routine worked.  The little program examined a number to determine if it was a
palindrome.  I used a divide like yours to get the rightmost digits to reverse
them.  When my paper came back, the instructor had scribbled all over it trying
to figure it out.  He said "I can see that it works, but I don't see how."  Just
to see if anyone else could figure it out, he took my little program (about 10
lines), changed all the labels to useless ones like A, B, C, etc. and listed it
with "What does this program do?" as a 20 point question on the midterm exam!
However, you have a good point that your method will work with earlier COBOL.
For that I would have used quotient and remainder fields and used DIVIDE GIVING
REMAINDER.  Compiler could have generated the same code, but with one extra
move instruction.

- Show quoted text -

Quote:
> > To test:

> >   if leap
> >   if not leap

> Hmm... I think it would indeed be better if I had used just one (positively
> phrased) condition name in stead of two. My "noLeap" is not necessary and
> makes even possible to use "not noLeap". Judson made a good point here.

> > PS- Try not to think too system specifically.  On many architectures,
> >     adding a sign when it is not needed, or using an 01 when a 77 will
> >     do is a waste.

> I admit tha adding the sign was a Pavlov reflex. I started on big blues!
> Adding a sign there as NO waste, but betters performance (no OR-immediates).
> Using 77 i.s.o 01 I never considered.

I suspected that was the case.  Not all systems address data in bytes.  Some
systems address much longer words, and extract the field using a word offset and
length, so it is as easy for them to address a half-byte or even a few bits as
to address a whole byte.  Other systems address less than a byte.  The Burroughs
Medium Systems addressed a half-byte, and the Burroughs Small Systems hardware
addressed to the bit.  On any of these architectures, the sign costs memory, and
on some architectures it could cost time too.
--
Judson McClendon          This is a faithful saying and worthy of all
Sun Valley Systems        acceptance, that Christ Jesus came into the

(please remove zzz from email id to respond)

Sat, 19 Aug 2000 03:00:00 GMT
the year 4000 problem

This boy is after me! And with some success, I must admit. Let me see if I can save
some of my face.

Huge 8< here

Quote:
> > > > if px = zero

> > You probably  made a typing error? px or pq?

> Actually, it was your error which I didn't catch.  It is copied verbatim from
> your original message.  ;-)

He got me. (grmbl)

Other large 8<

Quote:
> > Hey! that works, but feels costly (in cpu cycles) to me. Besides, my solution
> > works in older versions, even before COBOL '68, I think.

Hey. This one he silently ignored. Judson? Still there?

Quote:
> The COBOL compiler will almost certainly generate a divide to an intermediate
> field, and move the result into the receiving field.

Agreed. Sounds very reasonable.

Quote:
>  Almost any machine
> language divide is going to also provide the remainder as well.

He suggests a free remainder calculation. That I nearly can't believe. Anybody that
can prove his or my point? Some assembler boys out there, please help.

Quote:
>  It is as easy for the compiler to move the remainder to the result as to move the
> quotient to
> the result.

If he is right about the free remainder ...

Quote:
>  On some architectures, a MOD operator might be even more efficient.
> If the compiler generates efficient inline code for FUNCTION MOD, there should
> be no difference in the memory or CPU cycles.  It is also far more intuitive to
> understand than your

(My line feed)

Quote:
> clever YEAH YEAH (my YEAH YEAH)

(My line feed)

Quote:
> approach.  I did a very similar thing in a PL/I
> course back in the 70's, and the instructor never did understand how the
> routine worked.

8< a lot of text in which he tries to show how great he is as a programmar. By *I*
have the scissors in my hand. He he he he he.   ;)

Quote:
> However, you have a good point

(It happens quit often (blush))

Quote:
> that your method will work with earlier COBOL.

Aaaaah. There he is. At last. How hideous to admit that after so many lines

Quote:
> For that I would have used quotient and remainder fields and used DIVIDE GIVING
> REMAINDER.

To be fair, Judson is right. The code is much more readable with the remainder
clause.

8< again a lot

Quote:
> > I admit tha adding the sign was a Pavlov reflex. I started on big blues!
> > Adding a sign there as NO waste, but betters performance (no OR-immediates).
> > Using 77 i.s.o 01 I never considered.

> I suspected that was the case.  Not all systems address data in bytes.  Some
> systems address much longer words, and extract the field using a word offset and
> length, so it is as easy for them to address a half-byte or even a few bits as
> to address a whole byte.  Other systems address less than a byte.  The Burroughs
> Medium Systems addressed a half-byte, and the Burroughs Small Systems hardware
> addressed to the bit.  On any of these architectures, the sign costs memory, and
> on some architectures it could cost time too.
> --
> Judson McClendon          This is a faithful saying and worthy of all
> Sun Valley Systems        acceptance, that Christ Jesus came into the

Judson, you spoke some thruths. I'm curious what the assem goeroes will add (if they
do).

A Cobol Frog called Huib

Sat, 19 Aug 2000 03:00:00 GMT
the year 4000 problem

Quote:
> This boy is after me! And with some success, I must admit. Let me see
> if I can save some of my face.

I'm not 'after you', just trying to get the matter settled. :-)

Quote:

> Huge 8< here

> > > > > if px = zero

> > > You probably  made a typing error? px or pq?

> > Actually, it was your error which I didn't catch.  It is copied verbatim
from
> > your original message.  ;-)

> He got me. (grmbl)

> Other large 8<

> > > Hey! that works, but feels costly (in cpu cycles) to me. Besides, my
solution
> > > works in older versions, even before COBOL '68, I think.

> Hey. This one he silently ignored. Judson? Still there?

Hardly, the whole next paragraph addresses the points you made there.  ;-)

Quote:
> >  Almost any machine
> > language divide is going to also provide the remainder as well.

> He suggests a free remainder calculation. That I nearly can't believe.
Anybody that
> can prove his or my point? Some assembler boys out there, please help.

I AM an 'assembler boy' (well, assembly old guy).  Not on IBM mainframes, but
on a
number of other architectures, from microcode up.  What I said is the truth.
When I
said 'almost any assembly language', I was only leaving room for lack of
complete knowledge.  I do not know of any assembly language divide
instruction that does not
return both quotient and remainder, but there may be one somewhere.  One
reason is
that the processor is going to have the remainder available anyway, and it
generally
costs nothing to present it.  Another is that it would be more expensive to
extra divide for when you needed the remainder too.  Remainder is useful in
rounding,
dealing with high precision numbers, etc.  MOD is usually calculated with a
divide

Quote:
> >  It is as easy for the compiler to move the remainder to the result as to
move the
> > quotient to the result.

> If he is right about the free remainder ...

You can take it to the bank.

- Show quoted text -

Quote:
> >  On some architectures, a MOD operator might be even more efficient.
> > If the compiler generates efficient inline code for FUNCTION MOD, there
should
> > be no difference in the memory or CPU cycles.  It is also far more
intuitive to
> > understand than your

> (My line feed)

> > clever YEAH YEAH (my YEAH YEAH)

> (My line feed)

> > approach.  I did a very similar thing in a PL/I
> > course back in the 70's, and the instructor never did understand how the
> > routine worked.

> 8< a lot of text in which he tries to show how great he is as a programmar.
By *I*
> have the scissors in my hand. He he he he he.   ;)

Absolutely not.  I was simply pointing out how difficult it could be to
understand
that particular method.  I view these exchanges as sharing, not competition.
:-)
--
Judson McClendon          This is a faithful saying and worthy of all
Sun Valley Systems        acceptance, that Christ Jesus came into the

(please remove zzz from email id to respond)

Sat, 19 Aug 2000 03:00:00 GMT
the year 4000 problem

Judson completely outruns me with his knowledge of assembly. And so I lost. But
learned A LOT of new things. And so I won also. Thanks Judson.

Little frog

Sun, 20 Aug 2000 03:00:00 GMT
the year 4000 problem

I know that in the earlier discussions of the code to calculate if something
is a leap year, there was discussion of how it would perform and would it
work with older compilers, but I thought that I would add my '85 Standard
"favorite" method (mostly using the original data division stuff)

01  aYear.
03  cc  pic 99.
03  yy  pic 99.
01  aYearNum redefines aYear Pic 9(04).
01  leapSwitch  pic X.
88  leap   value "Y".
88  noLeap value "N".

Evaluate True
When Function Mod (aYearNum 4) not Zero
When Function Mod (aYearNum 100) Zero
and Function Mod (aYearNum 400) not Zero
Set noLeap to True
When Other
Set Leap to True
End-Evaluate

P.S. I haven't brought in a compiled source, so I apologize for any
typo/compiler errors.
--
+ +
+   Bill Klein -
"C" is a nice letter to START the name of your programming language
with
but I wouldn't want to end up there.

> original code snipped <

Sun, 20 Aug 2000 03:00:00 GMT

 Page 1 of 1 [ 12 post ]

Relevant Pages