"COBOL Rescues The Millennium" For as many years as I can remember, COBOL programmers have been writing programs which calculated dates for various business operations: the age of consumer debt, the annuity on an investment, the monthly payments on a mortgage, the exact date "nnn" days (weeks, months years) from now, etc,. For just as many years, programmers have known that a "time bomb" has been planted in many of these business applications. This is so because in the year 2000, the final year of the current millennium, many of these programs will incorrectly calculate these date operations. The problem has arisen because of a general misunderstanding about the rules regarding which years are Leap years, and which years are not. To state the rule succinctly, leap years are divisible by 4 but not divisible by 100 unless divisible by 400. This makes the year 2000 a leap year; it is divisible by 4 and it is divisible by 400. Many of the COBOL programmers I spoke to during the 60's and 70's, had little concern for this problem because a) they believed they themselves would not be around in the nineties to have to worry about it or b) their COBOL programs (and perhaps the COBOL language itself) would not be around in the nineties for them to have to worry about it or c) someone would invent a magical solution to this problem. Well, just short of the calamity that everyone anticipated, the problem has in deed been solved. Those who believed in some magical solution (choice "c" above) turned out to be right. The COBOL language has been modified this year to include 6 new functions for programmers to manipulate and calculate dates. Calendar Functions Illustrated Fortytwo new intrinsic functions have been added to the official American National Standard (ANS) COBOL 85 language. Six of these functions specifically deal with calendar and date operations. These new calendar functions are among the most useful for COBOL programmers. They will clearly save many hours of programming and debugging time. In fact, estimates range up to 25% for increased programmer productivity. The six new Calendar functions are: CURRENTDATE WHENCOMPILED INTEGEROFDATE INTEGEROFDAY DATEOFINTEGER DAYOFINTEGER
The CURRENTDATE function returns current date and time information from the operating system to the program. This function expands upon the ACCEPT...FROM capability already in the COBOL 85 language as illustrated in the following statements: ACCEPT todaysdate FROM DATE ACCEPT todaysjulian FROM DAY ACCEPT todaystime FROM TIME ACCEPT weekday FROM DAYOFWEEK In each of the statements above, the operating system returns a value, in a specific format, to the data name specified. The FROM DATE clause returns the Gregorian calendar date in 6 positions of (display) data in the format Y Y M M D D. The FROM DAY clause returns the date in Julian format, Y Y D D D. The FROM TIME clause returns the current operating system time in the format H H M M S S h h.11 Note the COBOL language committees were rather short sighted when they provide only two digits to represent the year. This is one reason (among others) why date operations in COBOL were not easily solvable. . For instance, the year 2000 would algebraically be considered less than the year 1999 (i.e. 00 is less than 99). This makes date arithmetic across century dates more difficult. As we approach the twentyfirst century, this problem has become much more visible. The new CURRENTTIME intrinsic function returns all of the above information (and more) or at least provides the means to derive this information. Furthermore this problem of twodigit years is now a thing of the past.
Given the following data items, we will illustrate how to use the various Calendar functions: 01 purchasedate. 05 purchaseyear PICTURE 9999. 05 purchasemonth PICTURE 99. 05 purchaseday PICTURE 99. 01 juliandateofpurchase. 05 purchasejulianyear PICTURE 9999. 05 purchasejulianday PICTURE 999. 01 currentdateandtime. 03 todaysdate. 05 currentyear PICTURE 9999. 05 currentmonth PICTURE 99. 05 currentday PICTURE 99. 03 todaystime. 05 currenthour PICTURE 99. 05 currentminute PICTURE 99. 05 currentseconds PICTURE 99. 05 currenthundreths PICTURE 99. 05 currentoffset PICTURE X. 05 currentoffsethr PICTURE 99. 05 currentoffsetmin PICTURE 99. To simply access all the date and time information from the operating system we might include a statement such as: MOVE FUNCTION CURRENTDATE TO currentdateandtime. The alphanumeric function, CURRENTDATE (one of two that has no arguments) returns 21 positions of (display) data, as outlined in the data description above for currentdateandtime. Notice the value of the year is given as 4 positions; the current time is given as 13 positions, 5 of which are for Timezone offsets from Greenwich mean time. The reader may be surprised to know (as I was when I learned it) that not all time zones are "integer hours" off from Greenwich mean time. There are some places on the globe where the time zone is 30 minutes or 15 minutes ahead/behind the time zones immediately adjacent. One such example is Iraq and Iran. While Turkey and Iraq share the same time zone, Iran is 30 minutes ahead of their time. Another such instance is the Chatham Islands just a few miles east of New Zealand. The time on the Chatham Islands is 15 minutes ahead of New Zealand. Hence the need for a "currentoffsetminutes" field. (See the map in the Appendix.)
Two new functions are provided for doing arithmetic with dates. These are the INTEGEROFDATE and INTERGEROFDAY functions. Both of these functions return an integer value which represents the number of days elapsed between the date provided in the argument and the arbitrary date of January 1, 1601. In the case of INTEGEROFDATE, the argument date is provided in calendar format (Y Y Y Y M M D D); for the INTEGEROFDAY function, the argument date is provided in Julian format (Y Y Y Y D D D). The arbitrary "base" date of January 1, 1601 was chosen among other reasons because day number one fell on a Monday. This is consistent with the DAYOFWEEK clause of the ACCEPT statement which considers Monday to be the first day of the week. So long as that base date is consistent, "integer dates" provide us with a means to use dates in calculations. That is, they can now be used in any arithmetic expression requiring a numeric value. For instance, we can find the number of days elapsed between two different dates simply by converting both dates to integer values and then using these values in a simple arithmetic statement as illustrated here: COMPUTE ageofdebt = FUNCTION INTEGEROFDATE (todaysdate)  FUNCTION INTEGEROFDATE (purchasedate) It makes no difference whether these dates are in different centuries, or incorporate leap years in their range. As long as the purchase date is after January 1, 1601, this calculation will work. (If by chance the purchase date is prior to 1/1/1601, this will have to handled manually.) Two new functions, DATEOFINTEGER, and DAYOFINTEGER, give us the "reverse" functionality we have just seen. For instance, if we provide an integer value as an argument, the function will return the date (either in Gregorian or Julian format) corresponding to that integer.
A very popular procedure in many COBOL programs is the conversion of dates from one format to another, i.e. from Julian format to calendar format or visaversa. We now have a very easy means of doing this as illustrated in the following example: COMPUTE juliandate = FUNCTION DAYOFINTEGER (FUNCTION INTEGEROFDATE (purchasedate)) Notice in this example above the argument of the DAYOFINTEGER function is another function identifier, FUNCTION INTEGEROFDATE (purchasedate). This is allowed since the DAYOFINTEGER function requires an integer value as an argument; the INTEGEROFDATE function returns an integer value and therefore is acceptable to be used as an argument for the DAYOFINTEGER function. Of course we could have reversed this operation and converted a Julian date to calendar format just as easily using the DATEOFINTEGER function: COMPUTE purchasedate = FUNCTION DATEOFINTEGER (FUNCTION INTEGEROFDAY (juliandateofpurchase)) The WHENCOMPILED function is the other new intrinsic function which has no argument associated with it. It simply returns 21 positions of display data representing the date and time (in calendar format) that the current executing object program was compiled. The exact format of the information returned is identical to the format of the returned value of the CURRENTDATE function, which also returns 21 positions of (display) data. This is a handy function to use when developing an application. As the source (and object) program goes through numerous revisions and as each revision is tested, it is convenient to have a means of identifying (stamping) the test output with the particular version of the application program that produced it. One might use the following statement as a means of identifying the output: MOVE FUNCTION WHENCOMPILED INTO reportheader In a subsequent paper, I will discuss some of the other 38 new intrinsic functions which deal with: character and string manipulation, numerical analysis, mathematical and statistical calculations, business operations, and trigonometric functions. For a complete description of all the new intrinsic functions in the COBOL 85 language, see "COBOL Functions Illustrated," by Jerome Garfunkel, published by Micro Focus. 
