function autoEuroDate(field, thisEvent) {															// autoEuroDate() helps the user to type a date in the European format 'dd/mm/yyyy'.
	var iCode = (window.Event) ? thisEvent.which : thisEvent.keyCode;						// The key pressed.
	var sDelim = "/";																						// Delimiter this code will insert. NB: this script treats these chars as a input delimiter: /.-
	var sStr = field.value;																				// The current value of the form field.
	
	if (iCode != 8) {																						// Only auto-complete if the user didn't hit Backspace (there is no keycode for Delete).
		switch (sStr.length) {																			// Decide what to do, based on the current length of the form field's contents.
			case 1:
				if (sStr.substr(0, 1).search(/[0-9]/) != 0)										// If they typed something other than 0-9, delete it.
					field.value = "";
				break;
			case 2:
				if (sStr.substr(0, 2).search(/([1-9][\/\.-])/) == 0)							// If they typed 'n/', 'n.' or 'n-', alter it to '0n/'.
					field.value = "0" + sStr.substr(0, 1) + sDelim;
				else if (sStr.substr(0, 2).search(/(0[1-9]|[1-2][0-9]|3[0-1])/) != 0)	// If characters 1 and 2 aren't 01 ~ 31, delete them.
					field.value = "";
				else																							// Otherwise, add the delimiter to what they've typed.
					field.value = sStr + sDelim;
				break;
			case 3:
				if (sStr.substr(2, 1).search(/\//) != 0)											// If the third character isn't the delimiter, replace it.
					field.value = sStr.substr(0, 2) + sDelim;
				break;
			case 4:
				if (sStr.substr(3, 1).search(/[\/\.-]/) == 0)									// If they typed a separator after it was automatically added, strip it.
					field.value = sStr.substr(0, 2) + sDelim;
				else if (sStr.substr(3, 1).search(/[0-9]/) != 0)								// Otherwise, if they typed something other than 0-9, delete it.
					field.value = sStr.substr(0, 2) + sDelim;
				break;
			case 5:
				if (sStr.substr(3, 2).search(/([1-9][\/\.-])/) == 0)							// If they typed 'n/', 'n.' or 'n-', alter it to '0n/'.
					field.value = sStr.substr(0, 2) + sDelim + "0" + sStr.substr(3, 1) + sDelim;
				else if (sStr.substr(3, 2).search(/(0[1-9]|1[0-2])/) != 0)					// If characters 4 and 5 aren't 01 ~ 12, delete them.
					field.value = sStr.substr(0, 2) + sDelim;
				else {
					var iDay = parseInt(field.value.substr(0, 2));								// Ensure they haven't typed in an invalid day for the month entered.
					var iMonth = parseInt(field.value.substr(3, 2));
		      	var iMaxDay = 31;
					
					if (iMonth == 4 || iMonth == 6 || iMonth == 9 || iMonth == 11)
						iMaxDay = 30;
					else if (iMonth == 2)
						iMaxDay = 29;
   
					if (iDay > iMaxDay)																	// Strip out the month if it's invalid, given the day the user entered (assuming 29 as max day for Feb).
						field.value = sStr.substr(0, 2) + sDelim;
					else																						// Otherwise, just append the delimiter.
						field.value = sStr + sDelim;
					}
				break;
			case 6:
				if (sStr.substr(5, 1).search(/\//) != 0)											// If the sixth character isn't the delimiter, replace it.
					field.value = sStr.substr(0, 2) + sDelim + sStr.substr(3, 2) + sDelim;
				break;
			case 7:
				if (sStr.substr(6, 1).search(/[\/\.-]/) == 0)									// If they typed a separator after it was automatically added, strip it.
					field.value = sStr.substr(0, 2) + sDelim + sStr.substr(3, 2) + sDelim;
				else if (sStr.substr(6, 1).search(/[1-2]/) != 0)								// Otherwise, if they typed something other than 1 or 2, delete it.
					field.value = sStr.substr(0, 2) + sDelim + sStr.substr(3, 2) + sDelim;
				break;
			case 8:
				if (sStr.substr(6, 2).search(/(19|20)/) != 0)									// Otherwise, if they typed something other than 19 or 20, delete it.
					field.value = sStr.substr(0, 2) + sDelim + sStr.substr(3, 2) + sDelim;
				break;
			case 9:
				if (sStr.substr(6, 3).search(/(19[0-9]|20[0-9])/) != 0)						// Otherwise, if they typed something other than 19[0-9] or 20[0-9], delete it.
					field.value = sStr.substr(0, 2) + sDelim + sStr.substr(3, 2) + sDelim;
				break;
			case 10:
				if (sStr.substr(6, 4).search(/(19[0-9]{2}|20[0-9]{2})/) != 0)				// If characters 7~10 aren't 19xx or 20xx, delete them.
					field.value = sStr.substr(0, 2) + sDelim + sStr.substr(3, 2) + sDelim;
				else {
					var iDay = parseInt(field.value.substr(0, 2));								// Ensure they haven't typed in an invalid day or month for the year entered.
					var iMonth = parseInt(field.value.substr(3, 2));
					var iYear = parseInt(field.value.substr(6, 4));
		      	var iMaxDay = 31;
					
					if (iMonth == 4 || iMonth == 6 || iMonth == 9 || iMonth == 11)
						iMaxDay = 30;
					else if (iMonth == 2) {
						if (iYear % 4 > 0)
							iMaxDay = 28;
						else if (iYear % 100 == 0 && iYear % 400 > 0)
							iMaxDay = 28;
						else
							iMaxDay = 29;
					}
   
					if (iDay > iMaxDay)																	// Strip out the month if it's invalid, given the day the user entered (assuming 29 as max day for Feb).
						field.value = sStr.substr(0, 2) + sDelim;
				break;
			}
		}
	}
}

function autoTime(field, thisEvent) {																// autoTime() helps the user to type a time in the form 'HH:mm'.
	var iCode = (window.Event) ? thisEvent.which : thisEvent.keyCode;						// The key pressed.
	var sDelim = ":";																						// Delimiter to replace. NOTE: this script treats thse entered by the user as a delimiter: /.-
	var sStr = field.value;																				// The current value of the form field.
	
	if (iCode != 8) {																						// Only auto-complete if the user didn't hit Backspace (there is no keycode for Delete).
		switch (sStr.length) {																			// Decide what to do, based on the current length of the form field's contents.
			case 1:
				if (sStr.substr(0, 1).search(/[0-9]/) != 0)										// If they typed something other than 0-9, delete it.
					field.value = "";
				break;
			case 2:
				if (sStr.substr(0, 2).search(/([1-9][\:\/\.-])/) == 0)						// If they typed 'n/', 'n.' or 'n-', alter it to '0n/'.
					field.value = "0" + sStr.substr(0, 1) + sDelim;
				else if (sStr.substr(0, 2).search(/([0-1][0-9]|2[0-3])/) != 0)				// If characters 1 and 2 aren't 00 ~ 23, delete them.
					field.value = "";
				else																							// Otherwise, add the delimiter to what they've typed.
					field.value = sStr + sDelim;
				break;
			case 3:
				if (sStr.substr(2, 1).search(/\:/) != 0)											// If the third character isn't the delimiter, replace it.
					field.value = sStr.substr(0, 2) + sDelim;
				break;
			case 4:
				if (sStr.substr(3, 1).search(/[\:\/\.-]/) == 0)									// If they typed a separator after it was automatically added, strip it.
					field.value = sStr.substr(0, 2) + sDelim;
				else if (sStr.substr(3, 1).search(/[0-5]/) != 0)								// Otherwise, if they typed something other than 0-9, delete it.
					field.value = sStr.substr(0, 2) + sDelim;
				break;
			case 5:
				if (sStr.substr(3, 2).search(/[0-5][0-9]/) != 0)								// If characters 4 and 5 aren't 00 ~ 59, delete them.
					field.value = sStr.substr(0, 2) + sDelim;
				break;
		}
	}
}

function isEuroDateFormat(sDate) {															// isEuroDateFormat() check that a string is in the format 'dd/mm/yyyyy' (and doesn't allow 'silly' years).
   regEx = new RegExp("^(0[1-9]|[1-2][0-9]|3[0-1])/(0[1-9]|1[0-2])/(19[0-9]{2}|20[0-9]{2})$", "gi");
   return regEx.test(sDate);
}

function isISODateFormat(sDate) {															// isISODateFormat() check that a string is in the format 'yyyyy-mm-dd' (and doesn't allow 'silly' years).
   regEx = new RegExp("(^19[0-9]{2}|20[0-9]{2})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", "gi");
   return regEx.test(sDate);
}

function isValidDate(year, month, day) {													// isValidDate() checks if you can make a valid date from three numeric arguments.
   if (day < 1 || day > 31) {																	// See if the day is obviously wrong.
      return false;
   } else if (month < 1 || month > 12) {													// See if the month is obviously wrong.
      return false;
   } else {																							// Otherwise, see if we can create a valid date.
      var maxDay = 31;
      
      if (month == 4 || month == 6 || month == 9 || month == 11) {
         maxDay = 30;
      } else if (month == 2) {
         if (year % 4 > 0) {
            maxDay = 28;
         } else if (year % 100 == 0 && year % 400 > 0) {
            maxDay = 28;
         } else {
            maxDay = 29;
         }
      }
   
      if (day > maxDay) {																		// Return false if the day is invalid for this month and year,
         return false;
      } else {																						// otherwise return true.
         return true;
      }
   }
}

function isValidEuroDate(sDate) {
	if (!isEuroDateFormat(sDate) || !isValidDate(sDate.substring(6, 10), sDate.substring(3, 5), sDate.substring(0, 2))) {
		return false;
	} else {
		return true;
	}
}

function isValidISODate(sDate) {
	if (!isISODateFormat(sDate) || !isValidDate(sDate.substring(0, 4), sDate.substring(5, 7), sDate.substring(8, 10))) {
		return false;
	} else {
		return true;
	}
}

function isValidShortTime(sTime) {															// isValidShortTime() checks that a string is in the format 'HH:mm'.
   regEx = new RegExp("^([0-1][0-9]|2[0-3]):([0-5][0-9])$", "gi");
   return regEx.test(sTime);
}

function now() {
	return new Date();
}

function parseEuroDate(sDate) {
	return new Date(sDate.substring(6, 10), sDate.substring(3, 5) - 1, sDate.substring(0, 2))
}

function parseTime(sTime) {
	var dTime = new Date(1899, 12, 30);
	var aTime = sTime.split(":");

	dTime.setHours(aTime[0]);
	dTime.setMinutes(aTime[1]);
	dTime.setSeconds(aTime[2]);

	return dTime;
}

function today() {
	var dToday = new Date();
	dToday.setHours(0, 0, 0, 0);
	return dToday;
}