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 applica-
tion:
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 Satur-
day.

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