
Microsoft Year 2000 Readiness Disclosure
& Resource Center |
 |
 |
 |
Preparing Office Solutions for the Year
2000 |
 |
Examining
Module Code
Module
code represents one of the more difficult challenges in making your
application Year 2000 compliant. Because code can represent dates in
so many ways, it can be difficult to find all of the date-related
logic in the application. Microsoft products support several
variants of module code, all based on the BASIC language:
Non-Compliant Procedural Code
Most
desktop applications contain macro and module code that manipulates
data in a procedural fashion. This brings up what could be the
costliest Year 2000 issue in terms of identifying and fixing
problems.
If
procedure code that works on dates is not written with Year 2000
compliance in mind, then its operations should be considered
suspect. For example, consider the following code snippet that
determines a credit card's expiration date based on the membership
date:
strYear =
Right$(Me!JoinDate, 2) ' Just lost the century
information!
intYear = CInt(strYear) + 5
Me!Expire =
Month(Me!JoinDate) & "/" & Day(Me!JoinDate) & "/" &
intYear
Code Listing 6 Examples of Non-Compliant
Procedural Code
This
code isn't Year 2000 compliant because it removes century
information from existing data before making its calculation. The
above code will generate incorrect results.
Identifying non-compliant procedural code is not something
that a utility program can do with 100% reliability. This is because
the code may not contain any words, phrases, expressions or numbers
that identify it as being date related. For this reason, finding
issues with procedural code can take more human intervention time
than any other area.
The Problem of Identification
The
typical approach is to search module code for any word or phrase
that identifies the code as date-related. For example, you can
search for all language keywords that deal with dates, such as
CVDate, DateValue, Year, etc. This technique should identify most of
the code that deals with dates. Other code may represent dates but
that fact may not be obvious from viewing the code. For example, the
following fictitious procedure adds two years to a string date:
Sub
AddIncrement () Dim str1 As
String Dim str2 As
String Dim str3 as
String
str1 = left$(strCurrent,
2) str2 = mid$(strCurrent, 3,
2) str3 = right(strCurrent,
2)
strNew = str1 & "/" & str2 &
"/" & CInt (str3) + 2
End Sub
Code Listing 7 Unidentifiable Date
Functionality in Procedural Code
This
code contains no calls to native date functionality, nor does it use
names that identify it as date related. This example shows how
difficult it can be to identify, let alone fix, procedural code.
Identifying Issues with String Dates
Anytime
that a date is represented by a string, you have the potential for
problems. This is because the string data type does not "understand"
what dates are, or the special rules that govern them. And use of
strings for dates in not uncommon in desktop applications. For
example, say you get the value of a Date/Time field from a Microsoft
Access form and assign it to a string variable. At that point, the
string variable is just an assemblage of characters, it has no
meaning as a date. Why is this a problem? Because most century
errors in date related code happen because they have been converted
to strings. Then, the string is decomposed into days, months and
years. Subsequent operations on that string or its parts are prone
to error unless century issues are handled explicitly by the code.
The
issue can be further clarified by thinking in terms of how variants
(and Date types in VBA) differ from strings. Date-type Variant or
Date variables always store the full four digits of the year. Even
when you display such a variable (in the immediate window, or on a
form) and only two digits of the year are shown, the full four
digits are still there. The century information is merely "hidden"
by the application according to the Short Date format defined in the
Control Panel.
Identifying Issues with Variant Dates
Access
Basic (the language in Access versions 1.0, 1.1 and 2.0) and Visual
Basic version 3 do not have a native date data type. It does support
date values through the variant data type. Most problems occur when
a variant date is used by module code, and the date already has
century errors.
For
example, assume that code gets a date from a form's control into a
variant. Microsoft Access automatically converts the value to
date-type variant, but by then, its too late. The century
information included in the date is based upon the rule that
Microsoft Access used when the user entered the value into the form.
So if only two digits of the year are entered, the variant will
contain the century dictated by whatever rule is in effect for that
version of Microsoft Access or Microsoft Visual Basic. In such a
case, the century information contained in the variant must be
considered suspect.
Creating Your Own Sliding Window Algorithm
If you
are using an application that doesn't use a sliding window
algorithm, you should write your own. Call this routine any place
your application could work with a two-digit year. And remember that
even though the newer 32-bit programs such as Microsoft Visual Basic
5, Microsoft Excel 97, and Microsoft Access 97 have a sliding window
algorithm, you must determine if the number used for the pivot year
is correct for your needs. If not, create and use your own sliding
window algorithm. See the sample code earlier in this paper for
details.
|