8

The LA Fox Developer Newsletter
December 1998
Take Care With Dates and Times
Don’t let date and datetime anomalies catch you out.

Visual FoxPro’s array of date and datetime functions normally work flawlessly ... but the results are not always what you might expect. For instance, assigning a “blank” date value to a variable, like this:
a = {0/0/0}
will correctly create a date variable. But assigning a blank datetime does not produce a datetime variable. Thus:
b = {0I0/0 0:00AM)
makes b a date, not a datetime as you might have thought.

Curiously, the following code does create an empty datetime:
b = (I:)

Another datetime anomaly is this construct:
{:}
which, for no obvious reason, translates to:
12/30/1 899 12:00:00AM

Migration

If you are migrating to VFP from FoxPro 2.x, be aware that the former is stricter than the latter in its use of date separators. For example, CTOD(1*12*98~) is valid in 2.x, regardless of SET SEPARATOR, but it generates an invalid date in Visual FoxPro.

Year 2000 issues

Visual FoxPro is, for the most part, Year 2000 compliant ... but care is needed. To demonstrate, let’s look ahead ten years from the day this article was written:
SET CENTURY ON
dAnniv = (12/30/07) && ten years from 12/30/97

Now subtract ten years from that date, like this:
? GOMONTH(dAnniv,-120)
The result is 12/30/1897— a hundred years earlier than you might have expected.

That’s not a bug. The point is that, when you specify a two-digit year, the century digits are always taken as 19— even if CENTURY is on, and regardless of the system date. If, during 1998 and 1999, your users will be entering forward dates for the next century contract expiration dates, for instance you might want to amend your forms to allow the full four-digit year to be entered.

By putting the following line of code at the start of your application:
SET CENTURY TO 20
you ensure that the century digits in a two-digit year are always
20.

Going further, this line of code:
SET CENTURY TO 19 ROLLOVER 45
says that the century digits in a two-digit year will be 19 if the last two digits are 45 or higher, otherwise the century digits will be 20. In many cases, adding this code will be the only action you need to take to allow your users to go on entering just the last two digits of the year.

By the way, these two forms of SET CENTURY were new to VFP 5.0. They won’t work with earlier versions.

Text box bug

If you use the DATEO function in a text box, and if the system date is 2000 or later, you will always see a four-digit year, regardless of SET CENTURY. This is a bug, which appears to be present in all versions of VFP. There is a simple workaround:
set the InputMask property to 99/99/99.

Give us back our eleven days”

You probably know that GOMONTHO can be used to add or
subtract a number of months to or from a date. Thus
GOMONTH({1/1/1 990},-12)returns
1/1/1980.

But try this: GOMONTH({12/31/1752},-12.The result is an invalid date. In fact, GOMONTHO fails for any date before September 14, 1753.

What is the significance of that date? There might be no connection, but it was on September 2, 1752 that Great Britain (along with its American colonies) finally got around to adopting the Gregorian, or New Style, calendar. To bring the country into line, an 11-day correction was needed. So September 2 was immediately followed by September 14.

We don’t know whether this in any way explains the quirk in GOMONTHO. But other Visual FoxPro date functions seem unaware of the date change. For example, CDOW({9/14/1 752)) correctly returns Thursday. But CDOW({9/2/1 752)) incorrectly returns Saturday it was in fact a Wednesday (at least in Great Britain).

Earliest date

Still in a historical mood, what do you suppose is the earliest date that VFP can handle? Not (0/0/00), which is considered to be an empty date. But (1/1/00), that is January 1 in the year zero, produces valid results with all the date functions. Pass it to CDOWO, for example, and you will see that it was a Saturday.

But this too is wrong. Why? Because there never was a year zero. In both the modern Gregorian calendar and its immediate ancestor, the Julian calendar, 1 BC was immediately followed by I AD. Perhaps the omission of a zero year was an oversight on the part of Sosigenes, the Greek astronomer who devised the
(Con’t, page 12)
Page 8

8