Clinick's Clinic on Scripting: Microsoft Script Engines and the Year 2000
Updated May 18, 1999
Everyone seems to be talking about the Year 2000 (Y2K) Problem and what effect it will have on the world's computer systems. I'm sure you've all heard how much a COBOL programmer can get paid to come out of retirement and fix the millions of COBOL programs that don't deal with the millennium. But have you thought about your script programs and how they might deal with the year 2000?
On the surface, it would appear that script programs written using Microsoft Visual Basic® Scripting Edition (VBScript) or JScript® should just be compliant, and most will be. In this article, I will cover the potential pitfalls in the languages, and also give you some tips on how to avoid the problem.
VBScript and JScript deal with dates very differently, so I will deal with them separately.
VBScript is a subset of the Visual Basic language; as a result, its date-handling functions are identical to Visual Basic's. Actually, if you follow Visual Basic closely, you'll know that some date-formatting functions first appeared in VBScript, then were added to Microsoft Visual Basic in version 6.0. Valid VBScript dates start in the year 100 A.D. and go through to the year 10,000 A.D., so I guess our descendants will have the Year 10,000 Problem. At least this article will have provided 8,000 years' warning of impending doom. This means that any three-, four-, or five-digit dates are dealt with perfectly, but two-digit year dates are special cases.
The main potential for problems in VBScript lies in the functions year and formatDateTime, and how your program uses them. The rule of thumb: If you use two-digit year dates, you're in trouble; no surprise there. The problems arise when you deal with dates in the high 20's. For example:
Dim MyDate, MyYear MyDate = #October 19, 29# ' Assign a date. MyYear = Year(MyDate) ' MyYear contains 2029. msgbox myYear
This will result in a VBScript msgbox of 2029, which is what you would expect. But if you change the code to
MyDate = #October 19, 30#
the message box will display 1930. This is because OLE Automation sets 1930 as the pivot date for dealing with two-digit year dates. Since VBScript, like Visual Basic, relies on OLE Automation for its date processing, it has exactly the same rules. This approach ensures that any Visual Basic code run in VBScript or Visual Basic will return the same dates, useful if you use both languages a lot.
FormatDateTime gives you more control over the date formatting that you access, but can still cause problems if you use two digits and are unaware of the 1930 pivot date. FormatDateTime gives you two ways to format a date:
- The long date format specified in your computer's regional settings
- The short date format specified in your computer's regional settings
If you use a two-digit year date (which, of course, you never will after reading this article), then you will get behavior similar to the year function if you use the long date format. For example:
Dim MyDate, MyYear MyDate = #October 19, 30# ' Assign a date. msgbox formatDateTime(MyDate,vbLongDate) ' Displays Sunday, October 19, 1930. Dim MyDate, MyYear MyDate = #October 19, 29# ' Assign a date. msgbox formatDateTime(MyDate,vbLongDate) ' Displays Friday, October 19, 2029.
Things get a little more complicated when you use the short date format. This format is defined by the settings on your machine (in this case, I'll assume you have U.S. English settings). The short date format on U.S. machines is mm/dd/yy, so if you use formatDateTime to get a date to assign to a database, then you should not use short date formatting, since it will only give you a two-digit year date. For example:
Dim MyDate, MyYear MyDate = #October 19, 30# ' Assign a date. msgbox formatDateTime(MyDate,vbShortDate) ' Displays 10/19/30. Dim MyDate, MyYear MyDate = #October 19, 29# ' Assign a date. msgbox formatDateTime(MyDate,vbShortDate) ' Displays 10/19/29.
All is not lost with formatDateTime, since, if you don't give it a format, it will by default return a fully formed date. So if you want a date that is fully Y2K compliant, and don't want the verbosity of a long date, call formatDateTime without any formatting information on a date with a fully qualified year. For example:
Dim MyDate, MyYear MyDate = #October 19, 1930# ' Assign a date. msgbox formatDateTime(MyDate) ' Displays 10/19/1930. Dim MyDate, MyYear MyDate = #October 19, 2029# ' Assign a date. msgbox formatDateTime(MyDate) ' Displays 10/19/2029.
Note that on Windows 3.1, VBScript does not support the long date option on formatDateTime because OLE Automation on Windows 3.1 lacks the long date feature. If you want to develop Y2K-compliant Web pages that run on Windows 3.1, you must use four-digit year dates. This is, of course, the recommendation for all date formatting, regardless of platform.
Date handling in JScript is a little more complex than in VBScript; the Y2K issue is somewhat more complicated as a result. As a program manager in the Microsoft Scripting Technologies group, I'm often asked how a language that didn't even exist until 1994 could possibly have any Y2K issues. Alas, I have no good answer, other than that JScript is a language with more than its fair share of quirks—this is, after all, the language that maintains that December is month 11!
If you are familiar with JScript, you will no doubt have come across the Date object. I won't go into detail here, since the object is documented fully in the JScript Language Reference on the Microsoft Scripting site, but just cover the areas where you might encounter Y2K problems. JScript will deal with dates, as defined in the ECMAScript spec, ranging from 100,000,000 days, which equates to approximately 285,616 years, before and after January 1, 1970.
When you create a date in JScript, you have a number of options. Either you calculate the number of milliseconds since Universal Coordinated Time (pretty guaranteed to be Y2K proof, but not exactly the most usable feature in JScript), or you specify a date yyyy,mm,dd.
var myDate = new Date(1930,9,19)
sets the date to be October 19, 1930, since month 9 is October in JScript (that's the last time I'll vent my feelings on dates being zero-based). Everything is fine if you enter a fully qualified date, but if you enter a two-digit year date, JScript assumes that you mean a year in the 20th century; thus, 20 will mean 1920, and so on. Dates are internally represented well within JScript, but problems begin when you use these dates within your programs and external storage.
Here are some examples:
// Set the date to October 19th 2020 var myDate = new Date(2020,9,19) // Displays Mon, 19 Oct 2020 07:00:00 UTC alert(myDate.toUTCString()) // Set the date to October 19th 20 var myDate = new Date(20,9,19) // Displays Tue, 19 Oct 1920 07:00:00 UTC alert(myDate.toUTCString()) // Set the date to October 19th 1920 var myDate = new Date(1920,9,19) // Displays Tue, 19 Oct 1920 07:00:00 UTC alert(myDate.toUTCString())
// Set the date to October 19th 20 var myDate = new Date(20,9,19) // Displays 20 alert(myDate.getYear()) // Set the date to October 19th 1920 var myDate = new Date(1920,9,19) // Displays 20 alert(myDate.getYear()) // Set the date to October 19th 2020 var myDate = new Date(2020,9,19) // Displays 2020 alert(myDate.getYear())
// Set the date to October 19th 20 var myDate = new Date(20,9,19) // Displays 1920 alert(myDate.getFullYear()) // Set the date to October 19th 1920 var myDate = new Date(1920,9,19) // Displays 1920 alert(myDate.getFullYear()) // Set the date to October 19th 2020 var myDate = new Date(2020,9,19) // Displays 2020 alert(myDate.getFullYear())
The last example brings up an interesting question: How do you set the date to be year 20 if the constructor on the date object treats 20 as 1920? This can be accomplished by using the setFullYear method so the following code will set the year to be 20:
// Set the date to October 19th 20 var myDate = new Date(20,9,19) myDate.setFullYear(20) // Displays 20 alert(myDate.getFullYear())
Both script languages have been upgraded to ensure that they have no inherent Y2K issues. We're still testing our Version 5.0 engines, so if you've found a Y2K bug please contact me via the e-mail link below or via the scripting newsgroups on msnews.microsoft.com. To ensure that your scripts are Y2K compliant, however, check that you are not using two-digit year dates in any code that results in the information being stored outside of the script.
We have only 16 months to go, so check those HTML pages and Web sites now.
Andrew Clinick is a Program Manager in the Microsoft Script Technology group, so chances are, if there's script involved, he's probably had something to do with it. He spends most of his spare time trying to get decent rugby coverage on U.S. television and explaining cricket to his new American colleagues.