Home | Web Design | Programming | Fairlight CMI | Soap Box | Downloads | Links | Biography | About... | Site Map |
Handling Dates - Solving the Year 2000 Problem |
CA-Clipper | Opportunities | Tips and Tricks | Networking | Internal Errors | Source Code | CA-VO |
BACK TO CA-CLIPPER TIPS & TRICKS |
There are many reports of the problems that companies face because
their software systems only support 2-digit years in dates. The year 2000
is indistinguishable from the year 1900 for many of these systems, which
will fail on January 1, 2000 unless they are corrected. So, the big question: is CA-Clipper year 2000 compliant? Definitely yes. CA-Clipper always manipulates dates internally with the complete date value, including the 4-digit year. Also, dates are stored in data (DBF) files as complete values in the format YYYYMMDD , for example
19971028. Visit my Data File Headers and the Year 2000 page for details about DBF headers. However, although CA-Clipper does not have a year 2000 problem, your programs might. |
Date Creation and the Format String Many programs manipulate date values by adding or subtracting days, or by finding the number of days between two dates. These calculations are generally not a problem if they use CA-Clipper's built-in date data type, but some programs use numeric or string values to represent dates. For example, the year, month, and day might be represented as separate numeric values and then merged to display a complete date. This should be avoided. Instead, use the built-in date data type which is "smart" because it knows how to handle the different month lengths as well as leap years. Creating a date value from separate year, month, and day numbers is error prone because of the different date format strings available. A date format string is used to specify how dates should look to the end user, but the format also affects how dates must be written in source code. For example, the default date format in CA-Clipper is MM/DD/YY
(the American format). To create a date variable from separate year, month,
and day variables you would use code like this:
nYear , nMonth , and
nDay ) are converted to strings and then concatenated with
slashes. The resulting string is then passed to the ctod()
function which creates a genuine date value from the string. If the date format is changed to DD/MM/YY , the preceeding code
will break unless it is re-written to match the order of the day, month,
and year in the date format string.
Since the effect of the date format string is "global", it alters all date construction throughout the program from the moment the set date format command is executed. Generally, global enviromment settings are not good because they represent an "invisible modification" of source code. Every line of source code should have a clear, unambiguous meaning but the reliance on global enviromment settings prevents this. Put another way, the meaning of a particular line of source code cannot be determined unless the values of the various global environment settings are known. Since the preceeding code relies on the value of the global date format string, it is fragile and unsafe. |
Two-digit Centuries and the Epoch Another problem with the code above is the specification of the year with only a two-digit value. The ctod() function detects this and
deals with it by checking the global "century reference point" as specified
with the set epoch command, which controls the interpretation
of date strings with only two digits for the year. When the string is converted to a date value, its year digits are compared with the year digits of the set epoch command. If the year
digits in the date string are greater than or equal to the year digits of
the set epoch command, the date is assumed to fall within the
same century as the set epoch command. Otherwise, the
date is assumed to fall in the following century. The default value for set epoch is 1900, causing dates with
no century digits to be interpreted as falling within the 20th century.
set epoch command as a "quick and dirty" way to fix
programs with year 2000 problems is not recommended. It is not a long-term
solution, as it only hides or postpones the problems. Depending on the type of date value, you might try the following approach. If dealing with birthdays, the epoch can be set to reflect the fact that birthdays are in the past.
ctod('28/10/95') and the epoch is 1897, then the
individual would seem to be 2 years old (born in 1995), rather than 102
(born in 1895). The epoch setting gives you a 100-year window, which is
insufficient for many purposes. This approach also fails with dates that fall within the same year as the current date, because of the uncertainty of whether the date is to represent this year or a hundred years in the future. |
Better Date Formats Many programs display dates as MM/DD/YY , for example 10/28/97.
This is typical of the American date format, which is the CA-Clipper
default. By adding set century on at the beginning of your
program, the format is converted to MM/DD/YYYY , like
10/28/1997. The longer date format may have an impact on your input
screens and reports. In other words, you may have to move things
around to make room. My preference is YYYY/MM/DD because it removes the ambiguity
inherent in certain date values. For example, what date is 12/03/97? Is it
December 3rd or March 12th? The American MM/DD/YY format is
world-renowned for the confusion it causes, whereas I believe that
1997/03/12 is clearly March 12th of 1997. When the year 2000 rolls around, March 12th would be 2000/03/12 rather than the strange 3/12/0. Other bizarre dates would be 1/2/3, 9/10/2, and 10/4/8, all of which would be clear if presented using the YYYY/MM/DD format! The international (ISO) standard date
format is YYYY-MM-DD , which I am starting to use. The ordering of the year, month, and day is as important as (and goes hand in hand with) the year 2000 problem. The Internet exposes your work to a worldwide audience, so regional date formats are not acceptable anymore. The YYYY/MM/DD format is unambiguous. Our job as programmers is to remove ambiguity. All of my source code has these lines at the beginning of the program (and nowhere else): set date format to 'YYYY/MM/DD' (By the way, set century on is redundant in this code
because the date format specifies YYYY , which implies
set century on . These two lines interact such that
set century off would change YYYY to
YY . This also means that the order of these two statements
is important.) Although I don't like to use, or rely on, such global environment settings, in this case it is unavoidable, and in fact too important to omit. The effect of these lines of code is to alter all input screens and reports to use the longer and more explicit date format. Users may complain that it takes too long to type '1997/10/28', but you'll never hear them say that they don't understand it. Note that there are many techniques to speed up entry of dates, such as providing a pop-up calendar and providing smart default (or automatic) values. |
Supported Dates and Storage Format The CA-Clipper documentation states that CA-Clipper supports all dates in the range 0100/01/01 to 2999/12/31. In fact, this is the range of dates that can be directly set, but dates outside this range can be reached by adding and subtracting days.
Data files, which have a file extension of DBF, are essentially text files. However, a binary header (which describes the layout of the data) appears first in the file. Each line of text is the same length and is organized according to the structure defined by the header. For example, given a table, CUSTOMER.DBF, with the following structure:
The first "column" indicates whether the record is deleted or not. In this case, the 3rd record is deleted, because there is an asterisk (*) in the column. This column is normally hidden by CA-Clipper. When this data is displayed within a CA-Clipper browse, it looks like this:
|
Year 2000 Compliance Notes and Links More detailed information on the headers of CA-Clipper and xBase tables can be found at Phil Barnett's Year 2000 and xBase Languages page. Although your CA-Clipper program may be corrected for any date problems, you should also examine your hardware and operating system. Perhaps surprisingly, many personal computers have a limited real-time clock (RTC) that does not handle 4-digit year values. When the computer is powered on, the BIOS software (in ROM) reads the date and time from the RTC and stores it in CMOS memory. Then, when the operating system (such as MS-DOS) loads, it reads the date and time from the CMOS memory and then maintains its own copy in another area of memory. The MS-DOS copy commonly "wanders" due to counter incaccuracies. The problems usually occur in the first two steps of this chain, the RTC and the BIOS. Test your computer by setting the date into the year 2000, then power off. If the date is still in the year 2000 when the power is turned back on, breathe a sigh of relief. Many older RTC chips wrap around to 1900, but when MS-DOS loads the date is "corrected" to 1980, which is the MS-DOS minimum. The maximum date in MS-DOS is the year 2099. Visit the premier Year 2000 site at http://www.year2000.com/ for full details and a program that will check your hardware's handling of future dates. You can download a program that shows you all three clocks (RTC, BIOS, and DOS), and whether they function correctly. The site also maintains a growing list of BIOS software versions and whether they are Year 2000 compatible. Most Unix systems store dates as signed 32-bit integers which contain the number of seconds since the January 1st 1970. Thus the final deadline to worry about in Unix is the year 2038. And I was always told that Unix was better than DOS... The Y2K web site at www.y2k.com explores legal issues related to the Year 2000 problem, otherwise known as the "Millenium Bomb". At the Y2K site the phrase "Year 2000 compliant" is defined in the Federal Acquisition Regulation; Year 2000 Compliance document:
Also at www.y2k.com is listed Four Criteria for "Century Compliance":
According to Science News (13 September 1997), the Defence Logistics Agency of the U.S. Department of Defense is working to fix 86 automated information systems, containing some 39 million lines of code, upon which it will rely after the year 2000. A recent incident involved 90,0000 items in the Defense Logistics Agency's materiel management program being removed from inventory as a result of a faulty year 2000 date calculation. Correcting the problem took 400 hours. [From EDUCOM Edupage, 1997/09/18 http://www.educause.edu/] A little "armchair statistics": if the other 85 systems suffer similar failures it will take around 17 man-years to correct, assuming 40-hour weeks. Given that there are only 2 years left, it appears that there is a problem. Throw more programmers at it, maybe. Another way of calculating is to assume that code can be inspected and corrected at a rate of 1 line per minute. At that rate, it would take over 300 man-years to check all code. Even though my calculations are very approximate, the scope of the issue is nonetheless clear. |
Summary
The following two functions do not rely on the current date format string.
|
Home | Web Design | Programming | Fairlight CMI | Soap Box | Downloads | Links | Biography | About... | Site Map |
Send comments about this site to Greg at
gregh@ghservices.com All pages copyright © 1996-1999 GH Services Created 1997/10/21 Last updated 2000/10/02 All trademarks contained herein are the property of their respective owners |