I've read more than one article about date range validation that relied on too much code for my taste, so I wrote simpler validation code that basically mimics how Excel calculates date ranges. This seems to be working without a hitch so far.
Let's assume you have two date fields: start_date and end_date. You want to ensure that end_date is at least 10 days after start_date, and of course you want this validation to work on leap years as well. In order for this date range validation to work, you'll need to create a third, hidden field that will contain the difference in days between start_date and end_date; let's call this field diff.
When start_date is entered, you convert this date string into a JavaScript date serial number, which is similar to an Excel date serial number but is the number of milliseconds since 1/1/1970. If the end date serial number is already defined, then calculate the difference in days and output it to the diff field. Write a similar OnAfterChange event handler for end_date. Once the diff field is populated, then you can use InfoPath's built-in data validation to ensure that the date range is at least ten days or whatever you want it to be.
Here's the complete code:
var nDateStart, nDateEnd;
var oDiff = XDocument.DOM.selectSingleNode('my:myFields/my:diff');
function msoxd_my_start_date::OnAfterChange(eventObj) {
var str = eventObj.Site.text;
if (str) {
// Normalize date format (yyyy-mm-dd -> mm-dd-yyyy)
nDateStart = Date.parse(str.replace(/(\d{4})-(.+)/,'$2-$1'));
if (nDateEnd) {
// Calculate difference (86400000 milliseconds = 1 day)
oDiff.text = (nDate2-nDate1)/86400000;
}
}
}
function msoxd_my_end_date::OnAfterChange(eventObj) {
var str = eventObj.Site.text;
if (str) {
// Normalize date format (yyyy-mm-dd -> mm-dd-yyyy)
nDateEnd = Date.parse(str.replace(/(\d{4})-(.+)/,'$2-$1'));
if (nDateStart) {
// Calculate difference (86400000 milliseconds = 1 day)
oDiff.text = (nDate2-nDate1)/86400000;
}
}
}
Cheers,
Tom
NOTE: If you want to count just business days, then read my other post, How to calculate business days. Even if you don't care about business days, the later post contains slightly improved code than what you see here.