FOCUS  Y2K  WHITE PAPER

Focus and the Year 2000 Problem
Author : Jay Converse
Mobil Global Information Systems

 
NOTE : THIS DOCUMENT WAS WRITTEN ORIGINALLY FOR  MOBIL’S  Y2K COMPLIANCE  EFFORT. 

        PLEASE  SEND  YOUR   CONTRIBUTIONS  TO  SUDARSHANA  RAMAKRISHNAN
       I will include it in this page.
 
 

Introduction :

This document is intended for all  Focus users, regardless of experience.  If you're a beginner, you can decide whether to solve Year 2000 problems yourself, or get help from a specialist.  If you're an experienced user or even an expert, this document will alert you to the most common problems, workarounds, and solutions.

What's going to happen in the year 2000?

Besides all the New Year's Eve parties?  Maybe nothing.  You may be among the very lucky people whose computer programs won't be affected.  Unfortunately, studies are showing that 80 90% of all programs will be affected by the year 2000 problem.  Some programs are already having problems, and a significant number will start having problems in 1999.

Some programs will stop working after an obvious error message, others will simply stop working.  The programs to worry about won't show symptoms at all.  They'll just give incorrect results, like mis-scheduled events and bad sales projections..
Do you have a problem?
Maybe.  If you have dates in your programs, then probably.  Even if you don’t work directly with dates, you may still be affected by Year 2000 changes if your program uses production data.  There are many databases that will be modified in the next three years, and unless you're aware of changes by the production teams, your programs may suddenly ‘crash’.
 

The good news and the bad news

The good news for Focus is that it has extensive date formats and functions.  The latest version has been made 'Year 2000 aware', so that some programs will not have to be changed at all.

The bad news for Focus is that lots of old programs used dates as a six digit alphanumeric field.  It was easier to continue with the old functions then rewrite and retest with a smarter field.  The big job now is to find and convert the old ways to the new ways.

 

Common Pitfalls, or "The Seven Deadly Sins of Y2K"

1.  Hard-Coded Century

This is the easiest problem to find, and often occurs in reports. It happens when the characters '19' are added to the front of a six-digit date.  In Focus, there are three common variations:

 Between quotation marks:

-SET &PRINTDATE = '19' | &YMD;
       or
COMPUTE  PRINTDATE/A8YYMD = '19' | INDATE;

 Next to a dialogue manager variable:

HEADING
"Printed: 19&YMD at &TOD"

 Next to a spot marker:

ON ENDYEAR SUBFOOT
"Subtotal for 19<ENDYEAR : <TOTDOLLARS"
 

How to find it:
This strings are fairly easy to find with a search program.  There may be a few extra lines located in cases where '19' means such things as the first part of an account code, or a
 partof

How to fix it:
For Dialogue Manager programs that use today's date, Focus has new system variables in version 7.0.  The general format is:

  &DATEfmt

where 'fmt' can be set to all of the regular 'new date' format options.  The limitation on these variables is that they only contain today's date - you can't assign a new value to them.  Still, they can be quite useful in reports and screens where &YMD or &DATE are used today.

For TABLE, DEFINE, COMPUTE, and MODIFY, the only way to fix hard-coded 19's is to change the variable to the 4-digit year equivalent.  Using the last example above, do this:

DEFINE FILE REVENUE
ENDYEAR2/YYMD = ENDYEAR;
END
TABLE FILE REVENUE
SUM TOTDOLLARS
BY ENDYEAR2
ON ENDYEAR2 SUBFOOT
-*"Subtotal for 19<ENDYEAR : <TOTDOLLARS"
"Subtotal for <ENDYEAR2 : <TOTDOLLARS"
END
 
2.  Dates have special meanings

Does ‘12/31/99’ mean ‘Forever’ or 'end of file' to your program?  Do you have a prompt that says "Enter the Year to extract or type '00' to quit"?

How to find it:
To find this problem in your programs, you could search for the strings '99' and '00'.  However, these strings occurs frequently in Focus programs especially in the EDIT function, so you would have to search through lots of good code before you found the problem.   It will be more productive to use your experience with the program to answer this question.

How to fix it:
Let's say you have a database where '12/31/99' means 'No data found', or 'Invalid entry', or 'Last record in the database'.  Before you can fix it, there are two things you need to think about.  First, what will happen when 12/31/99 becomes a 'real' date?  Remember, that's Friday, a regular business day.  If you remove the special meaning on this field, then you'll suddenly have a database filled with regular transactions for December 31, 1999.  Second, what value can you use as the new 'special' date?  All zeroes?  All nines?  You may not be able to create a new fake date if the field is validated somewhere else.  If you have the option of expand the year to four digits, then your 'special' date could be '12/31/9999', which isn't a bad solution.  If expansion is not an option, then the solution is not to use 'special' date fields to control the program, in which case you'll need to change the logic.

If you have a Dialogue Manager program in which entering '00' in a year means 'Quit', then there is no other option except changing the logic.  That is, of course, unless you don't plan to do any business until 2001!  If you have a prompt where you need to enter '00' and press 'Enter', consider changing the 'Exit' input to an 'X' or a 'Q'.

3.  Validations using part of the date

Does your program compare two dates?  For example, does it make sure that the 'shipment date' is not before the 'order date'?  Does your program make sure that input is greater than a certain year?  A very common method of validating a 2-digit year is to make sure it's after a 'reasonable' year like '80'.  Unfortunately, '00' is less than '80', so your data will be rejected.
 

How to find it:
There is no "industry-standard threshold year" that you can search for.  The low threshold could be most any decade since 1950.  And occasionally, theres' an upper threshold of '99', which means you might have a program that's going to break at the end of 1998!  Generally it's been up to the whim of the programmer to pick threshold years.  Unless you want to search the source code in detail, you'll need to rely on your personal experience with the program.

The brute force method of finding this problem is to run the program and enter '00' in every available date field, and see if you get an error message.

The other method of finding this problem is to search the code and find it indirectly.  Sometimes it will turn up around 'YMD' and 'MDY' .  You could also search for a message such as 'invalid year' or 'year must be'.

It might appear like this (MODIFY):

CASE GETDATA
COMPUTE INDATE/A6MDY = ;
CRTFORM
...
COMPUTE
   INMONTH = EDIT(INDATE,’99’);
   INDAY   = EDIT(INDATE,’$$99’);
   INYEAR  = EDIT(INDATE,’$$$$99’);

VALIDATE
   GOODONE = INYEAR GT ‘80’;
   ON INVALID TYPE “Please enter a year after 1980”
   ON INVALID GOTO GETDATA
...
ENDCASE

or this (Dialogue Manager):
-GETDATE
-PROMPT &INDATE.Please enter a date(MMDDYY).A6.
-SET &INMONTH = EDIT(&INDATE,’99’);
-SET &INDAY   = EDIT(&INDATE,’$$99’);
-SET &INYEAR  = EDIT(&INDATE,’$$$$99’);
-SET &MSG = IF &INMONTH LT ‘01’ OR &INMONTH GT ‘12’ THEN
-           ‘Invalid month’ ELSE
-           IF &INDAY LT ‘01’ OR &INDAY GT ‘31’ THEN
-           ‘Invalid day’ ELSE
-           IF &INDYEAR LT ‘80’ OR &INYEAR GT ‘99’ THEN
-           ‘Invalid year’ ELSE ‘ ‘;
-IF &MSG EQ ‘ ‘ GOTO GOODDATE;
-TYPE &MSG
-GOTO GETDATE
-*--------------------------------------------------
-GOODDATE
...
 

How to fix it:
The best way of fixing this problem is to remove it.  Simply 'comment out' any logic that validates or restricts a year to a certain range. The original logic was put in to protect the user from data entry mistakes.  To make it work 'correctly' again, you need to revisit the arguments of what a 'good' year is with the users.  This could make logic even more complicated than before.  You don't have time for that now.

If you can expand the year to four digits, then the validation must also be expanded.  For example, from 'Year must be greater than 80' to 'Year must be greater than '1980'.

4.  Arithmetic calculations

Do your programs calculate elapsed time between dates?  Many do.  For some time, Focus has had FUSELIB functions that work quite nicely with the old A6 and I6 dates.  However, the manual states clearly that these functions only work in the 20th century, and tests have proven it.  For example, the YMD function calculates the difference between two A6YMD fields.  Look at the following code sample:

DEFINE FILE TESTDATE
DATE1/A6YMD  = '990101';
DATE2/A6YMD  = '000101';
DIFF/I6 = YMD(DATE1,DATE2);
END
TABLE FILE TESTDATE
PRINT DATE1 DATE2 DIFF
END
 

PAGE     1
 
 
DATE1      DATE2        DIFF
-----              -----                ----
99/01/01    00/01/01       -36159

                                END OF REPORT

The answer should have been 365.  The new features in Focus 7.0 (DEFCEN, YRTHRESH) do not have any effect on these functions.

How to find it:
These are the date functions that are stuck in the 20th century:

 AYMD AYM  YM  YMD  MDY  DMY
 CHGDAT JULDAT GREGDT

Include these strings in your searches.

How to fix it:
Since these functions are used in DEFINEs and COMPUTEs, fixing the problem means adding or replacing fields with 'new' dates.  Using the sample above, the fix is:

SET DEFCENT = 19
SET YRTHRESH = 50
DEFINE FILE TESTDATE
DATE1/A6YMD  = '990101';
DATE2/A6YMD  = '000101';
DATE3/YMD = DATE1;
DATE4/YMD = DATE2;
DIFF/I6 = DATE4 - DATE3;
END
TABLE FILE TESTDATE
PRINT DATE1 DATE2 DATE3 DATE4 DIFF
END

PAGE     1
 
 
DATE1     DATE2     DATE3     DATE4       DIFF
    -----            -----           -----            -----           ----
99/01/01   00/01/01    99/01/01    00/01/01       365

                                END OF REPORT
 

As you can see, DATE3 and DATE4 print the same as before, but now the calculation is correct.

5.  Sequence

Is your output sorted by 2-digit years?  '00' comes before '99', so a sales report that spans 6 months could come out like this:

MYRPT FOCEXEC     Sales by Month From 99/09 to present
Run: 02/29/2000                ($000)

YEARMON    SALES
------                  ------
00/01             6,789
00/02             4,321
99/09                876
99/10             2,345
99/11             4,567
99/12             5,678

TOTAL     24,576
 

In the sample above, the results are ugly, but the correct answer is still available.

However, if the statements 'LAST', 'FIRST', 'LOWEST x', or 'HIGHEST x' are used against two digit years, then the results would be wrong. If the report above was generated with the statement 'BY HIGHEST 6 YEARMON', then nothing in the year 2000 would be selected as long as there was sales data from 1999!

How to find it:
To find this problem, you have to know how your data and how your reports are built.  If you have A6YMD or I6YMD fields in your database and you sort on these fields, then you have a potential problem.  Even if your database has all 'smart' dates, that's no guarantee that a 'dumb' date has been DEFINEd just for a report.

You can search for 'FIRST', 'LAST', 'HIGHEST', and 'LOWEST' to find the places where the report would definitely have a problem.  In the end, though, careful inspection is the best way to find this problem.

 
How to fix it:
Since 'smart' dates sort correctly regardless of their display format, the best and perhaps only way to fix this problem is to define new fields.  A6YMD becomes YMD, I4YM becomes YM, etc.

Version 7.0 features work very nicely in this respect.  The internal values assigned to the new fields will depend on the settings for DEFCENT and YRTHRESH.  In other words,

DEFINE FILE TESTDATE
DATE1/A6YMD = '000101';
DATE2/YMD   = DATE1;
DATE3/YYMD  = DATE1;
END
TABLE FILE TESTDATE
PRINT DATE1 DATE2 DATE3
END
 

PAGE     1
 
 
DATE1     DATE2     DATE3
-----               -----             -----
00/01/01  00/01/01  2000/01/01

                                END OF REPORT

 

6.  Historical data integrity
Do you have historical data in your database from around 1900?  Especially if  parts of your corporation are over 100 years old, it's possible.  In this situation, using the 'windowing' features of Version 7.0 will not work, since any given window only spans 100 years.

How to find it:
You have to know your data.  Period.  Real estate, fixed asset accounting, and personnel systems are the most common places where data spans centuries.

How to fix it:
Since 'smart' dates have been available in Focus for several years, in all likelihood any database that has historical data already has them in that format, or at least A8YYMD.

These sort correctly regardless of their display format, the best and perhaps only way in this circumstance, you'll have to rebuild your database, and expand the date fields from 6 to 8 digits.  There's no other reasonable way to fix it.

Another potential problem with historical data is if you already have dates in 'New' date formats YMD or MDY for the year 2000 and greater. Focus 7.0.6 is Year 2000 compliant, but previous versions were not, so even 'New' dates without the DEFCENT &
YRTHRESH  options will not work.

7.  Leap year Calculation
2000 A.D. *IS* a leap year.  This may seem obvious to most people, because it's divisible by four.  However, most centuries are NOT leap years, e.g., 1900 A.D.  Centuries divisible by 400 (1600, 2000, etc.) are exceptions to the exception.

Most users don't write their own leap-year calculations, so the odds that one of your programs has this problem are extremely low. But still possible...

How to find it:
You have to know your programs.  But let's be realistic.  If you're skilled enough to write your own leap year routines, you belong in an IS department, not a business department.  A search of  5,000 programs on MVS (626,000 lines) revealed no occurrences of 'user-written' leap year calculations.

How to fix it:
Focus 'new' dates correctly take care of leap years, so any home-grown leap year calculation should be converted to use the new date format.  Remember that the FUSELIB routines that are stuck in the 20th century (YMD, CHGDAT, etc.) won't work here.



                                                            NEXT PAGE