Y2K by Bryan White

Mmain article, plus interesting box for calculation of Easter.


The beauty of computers is that they do what you tell them.

The problem with computers is that they do what you tell them.

Computer processes generally use dates for two purposes: calculating days (or other time periods) between two dates, or for timestamping some event, which may then be sorted.

It is true that, unless deliberate action is planned and executed, the year 2000 (Y2K) will cause (and in some cases, has already caused) serious problems with computer systems. What is not true, is that extensive and expensive rewriting of entire computer systems is always needed to fix the problem.

Blind Dates …

I won’t spend much time recapping what most of you already know. Many computer systems use or display only two digits for the year component of dates. We do this ourselves without thinking, such as when reading and writing dates of birth. To reconstruct the full 4 digits, we preface these with an implicit ’19.’ However, when your new credit card arrives with an expire year of ‘00’, you realise that a prefix of ‘19’ doesn’t make sense, make it ‘20’, and decide that a new card that expires in three years’ time makes more sense than one that expired 97 years ago. If your computer system insists that a year of ‘00’ or ‘01’ is of Victorian vintage, then you have a problem.

I would now like to tell you what you may not know. If your computer system could intelligently decide the prefix, would all then be well? Perhaps. There is more to consider, and much depends on exactly how the year is stored internally as well as how it looks to the user. Programming languages like dBASE (even dBASE III) store dates into a structure with the century. SET CENTURY ON can be used to input and display the extra digits. This may fix the problem with an almost trivial program change.

Options that could be taken.

Where the design does not allow room for the leading digits that record centuries, there are other ways through the problem; if we can find a way of inserting ‘agents’ into the system that provide an alternative way to ensure that both of those date activities transcend the 1999/2000 event horizon, we can delay the need for a major rewrite. By ‘agent’, I mean a single purpose module that understands little of what is going on, other than its assigned task. The form of these does not matter. It may be a chunk of ‘inline’ code, a user defined function or a module call that, say, decides whether to add 1900 or 2000 to the years, or even just another 100 if year is less than 20. Some lateral thinking of mine has also come up with the idea of adjusting all dates BACKWARDS 28 years. Here are some details of the various procedures that may be used.

"If year < 10 then year = year + 100"

This will often do the trick for calculations, but indices or sorts may put the year 2000 records before any 1990 dates. Usually this is just cosmetic, and only a transient issue over the rollover period. Incidentally, if your computer BIOS only handles 2 digits for year, it can usually be overcome with a software fix with similar logic.

"If year < ‘10’ then store year as ‘A0’ + year"

If the date is stored as a ‘display’ field (i.e. not packed or binary), consider storing 2000 as A0 and 2001 as A1. A simple routine will convert that to numbers for arithmetic use. Sorts will work properly and reports will be in order.

Internal Year = External Year - 28

Another novel approach is to store all dates as (year - 28). This is good news, and bad news. The good news is that sorts will work, but the bad news is that any reports will need to be modified to ADD 28 to any dates. Why choose 28? Well, you can guarantee that the day of the week and any day differences will be the same (between 1928 and 2099). All holidays would calculate the same except Easter. This calculation would need to be altered by 28 years, but that is not difficult.

What are the possible pitfalls of a ‘cut down’ approach to the Y2K problem? Well, adding 100 to the year will not work if the storage space is 2 digits; changing storage size might be too tricky. Moving the clock back 28 years means that the program works alright, but note that most PCs will not accept a current date 28 years ago (they won’t go back beyond 1980). Another problem is that date input and reports need to be adjusted by 28 years. In dBASE, this can be accomplished with simple user defined functions.

Do not forget that there is also the file conversion exercise to consider. Personally, I think that an upgrade that leaves present data untouched is preferable to one that either manipulates the fields or extends them. If you hit a snag with conversion, you may have burnt your bridges.

Large Overgrown Systems

It is unusual for even a large mainframe to have more than a couple of million lines of code. This makes it possible to load the entire source code onto a PC. The approach varies depending upon whether you have a Data Dictionary system. In essence, change each date field name to reflect its format. EE-DOB might become EE-DOB-YYMMDD or EE-DOB-DDMMYY. Once all these have been done, it then becomes simple, via the concept of ‘agents’, to rewrite the program to become year-2000 compliant without even understanding what the program does! I have used this approach in the past for conversions, and afterwards people have assumed that I have become an expert on the system. Not so. Check closely if anyone tells you that they must understand the system to change it.

You may think that my thoughts are quite off the wall, but I invite you to think carefully about the Y2K issue - its solution may not be as expensive as you have been told.

Finally, two points to ponder. Company directors may be personally liable if they fail to prepare for the year 2000, and the year 2000 is the last year of the twentieth century, not the first year of the 21st century.


Easter Bonus - when would it be due?

Easter Day courtesy of God. Formula courtesy of Gauss

NB mod(N,B) must give answer in range 0 to (B-1)

Y = 4 digit year. M=24 & N=5 for 1900-2099

A = mod(Y,19)

B = mod(Y,4)

C = mod(Y,7)

D = mod(19*A + M,30)

E = mod(2*B + 4*C + 6*D + N,7)

Easter = 22+D+E in March, or D+E-9 in April, EXCEPT ...

... Instead of April 26, use April 19

... If D=28 and A>10 then instead of April 25, use April 18