Date validation on global servers

Jake Howlett, 13 October 2000

Category: JavaScript; Keywords: Date Format

Are you creating databases that live on servers all around the world and worried that you don't know which format the server expects dates to be entered in to fields of the date/time data type?

You can use this method to be sure that dates get validated to the correct format, mm/dd/yyyy or dd/mm/yyyy depending on the settings of the server you are using.

First thing to do is find out which format the server uses. We can do this with a simple @Formula like the one below:

DateText:=@Text(@Date(2000; 12; 31); "D0S0");
Replace := "31" : "12" : "2000";
With := "dd" : "mm" : "yyyy";
@ReplaceSubstring(DateText; Replace; With)


This creates a reference to my New Year's Eve, year 2000, in text format and then replaces the day with dd, the month with mm and the year with yyyy. It can do this as it knows that where the 31 appears in the date string is the day part and the where the 12 appears is the month. The trick is that, with domino, this formula is computed on the server so the format is independent of the client's location.

The best way to use this code is to place it in a "hidden" computed for display text field called DateFormat that is on all your forms. JavaScript can then get the value of this whenever it needs to validate a date field.

Image

Notice in the technique used above the HTML for the field is generated explicitly*.

We now have a dynamic value on every form accessible to JavaScript. On this site (hosted in America) the code generated is:


<input name="DateFormat" value="mm/dd/yyyy" type="hidden">


Now we need to create the JavaScript that is going to use it. The following function returns true or false depending on whether or not the value of the field object passed to it matches the pattern of the format passed to it:

function ValiDate(obj, format){
dateBits = DateComponents(obj.value, format);
if (dateBits == null) return false;

day = dateBits[0];
month = dateBits[1];
year = dateBits[2];

if ((month < 1 || month > 12) || (day < 1 || day > 31)) { // check month range
return false;
}
if ((month==4 || month==6 || month==9 || month==11) && day==31) {
return false;
}
if (month == 2) {
// check for february 29th
var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
if (day>29 || (day==29 && !isleap)) {
return false;
}
}
return true;
}


The next function needed, as it is called during the above function, is used to split the format string in to an array that lets the validation routine know the numeric value of day, month and year:

function DateComponents(dateStr, format) {
var results = new Array();
var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/;
var matchArray = dateStr.match(datePat);

if (matchArray == null) return null;
// parse date into variables
if (format.charAt(0)=="d"){ //format=dd/mm
results[0] = matchArray[1];
results[1] = matchArray[3];
} else {
results[1] = matchArray[1];
results[0] = matchArray[3]; }
results[2] = matchArray[4];
return results;
}


So, whenever you need to make sure a field has a valid date entered, you just need to call the ValiDate function (notice the play on words!). For example, a Date of Birth field (dob) like the one below. Notice that, in order to help the user there is a Computed Text hotspot next to the field that diplays the format that is required.

Image

You can validate the entry however and whenever you like. For example, the onChange event could be set to alert the user to invlaid dates, as below, or the form's onSubmit event.

alert( (ValiDate( document.forms[0].dob, document.forms[0].DateFormat.value) ? 'Date is OK!' : 'Date is BAD!');

Test it here:
(format=mm/dd/yyyy)


Note: You can see all these techniques being used in my JavaScript Form Validator database. Beware though, this is not a simple database and, although it will take a lot to figure out what is going on, I think it is worth it ....

*This could be achieved simply by entering "type=\"hidden\"" in the HTML Attributes but this technique is worth demonstratin as it can come in useful every now and then. Read this document if you want to know why it is so useful.