//May 17, 2007
//isDate(dateObject) as Boolean
//dateAdd(daetpart, interval, date) as Date
//dateCompare(date1, date2, dateType) as Integer
//stringToDate(date, format)

//create some date and time constants
var MILLISECOND = 1; // ms
var SECOND = MILLISECOND * 1000; // s
var MINUTE = SECOND * 60; // n
var HOUR = MINUTE * 60; // h
var DAY = HOUR * 24; // d
var YEAR = DAY * 365; // y

//create an array of DAY names
var _DN = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
//create  an array of short DAY names
var _SDN = new Array();
for (var i = 0; i < _DN.length; i++) _SDN[i] = _DN[i].substring(0,4);
//create an array of MONTH names
var _MN = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
//create an array of short MONTH names
var _SMN = new Array();
for (var i = 0; i < _MN.length; i++) _SMN[i] = _MN[i].substring(0,4);

//*******************************************************************************'
//make sure that a date is valid, and not something like February 30
//for strFormat only valid characters are:
// m = Month (1 = January)
// d = Day
// y = Year
// h = Hour (24 hour format)
// n = Minute (n as in Nancy)
// s = Second
// all other characters are treated as delimteters

//strDate must only contain numeric date parts i.e. 4 or 04 and not April

function isDate(strDate, strFormat) //as Boolean
{
	//if strFormat is not passed, default
	if(arguments.length == 1)
	{
		strFormat = "m/d/y";
		//strFormat = "m/d/y/ h:n:s"
	}
	
	//make sure strDate is a string
	strDate = String(strDate);
	
	//remove all A-Z characters save for m,d,y,h,n,s
	strFormat = strFormat.replace(/[abcefgijklopqrtuvwxz]/gi, '');
	
	//replace any double occurances of the codes
	strFormat = strFormat.replace(/([mdyhns])([mdyhns])+/gi,"$1");
	
	//if strFormat is less than / equal to 4 characters it is invalid
	//minimum format is m/d/y = 5 characters
	if(strFormat.length < 5)
	{
		alert("Invalid format. (character count)");
		return false;
	}
	
	//if i do not find 2 or more characters other than A-Z it is invalid
	//there is a minimum of 2 delimeters in m/d/y
	if(strFormat.match(/[^a-z]/gi).length < 2)
	{
		alert("Invalid format. (delimeter count)");
		return false;
	}
	
	//if i find 2 delimeters next to each other it is invalid
	//that's just stupid
	if(strFormat.search(/[^a-z]{2,}/gi) > 0)
	{
		alert("Invalid format. (double delimeter)");
		return false;
	}
	
	//at the end if the syntax test, test for a valid date value
	//i.e. make sure the user is not trying to enter February 31, 2006 or 13/13/2006
	//save each part of a valid date
	var theMonth = 0;
	var theDay = 0;
	var theYear = 0;
	var theHour24 = 0;
	var theMinute = 0;
	var theSecond = 0;

	//create the regular expression string
	var strRegExp = '';
	
	//save which character we are looking at in strFormat
	var chr = '';
	
	//save the delimeter after the code
	var delimiter = '';
	//save the Position if the delimeter in strForamt
	var delimeterPos = -1;
	
	var startPos = -1;
	var endPos = -1;
	
	//for each character in strFormat
	for(var i = 0; i < strFormat.length; i++)
	{
		//get a character
		chr = strFormat.charAt(i);
		
		//if this is a code..
		if(chr.search(/[mdyhns]/) == 0)
		{
			//look forward for the delimeter
			for (var j = i + 1; j < strFormat.length; j++)
			{
				//get the character
				delimeter = strFormat.charAt(j);
				
				//if this character is not m,d,y,h,n,s...
				if(delimeter.search(/[^mdyhns]/) == 0)
				{
					//save the delimeter
					delimeter = strFormat.charAt(j);
					
					//if this delimeter is at the very end of the strFormat, delete it
					if(j == strFormat.length - 1)
						strFormat = strFormat.substring(0, j -1)
					
					//break from this for loop
					break;
				}
			}//end for
			
			//start extrtacting from
			//if the startPos has not been defined, get the position from the current strFormat position
			//else it is 1 character after the last extraction
			startPos = (startPos < 0) ? i : endPos + 1;

			//end position is where the delimeter is or the end of the string
			endPos = ((i + 1) >= strFormat.length) ? strDate.length : strDate.indexOf(delimeter, startPos + 1);
			endPos = (endPos == strDate.length - 1) ? strDate.length : ((endPos == -1) ? strDate.length : endPos);
			
			//alert("startPos: " + startPos + "\nendPos: " + endPos)
			
			//we know which code we are currently looking at and we know the delimeter
			switch (chr)
			{
				case "m":
					theMonth = strDate.substring(startPos, endPos);
					break;
					
				case "d":
					theDay = strDate.substring(startPos, endPos);
					break;
					
				case "y":
					theYear = strDate.substring(startPos, endPos);
					if( theYear >= 2000 ) theYear -= 2000;
					if( theYear > 1900 ) theYear -= 1900;
					theYear -= (theYear > 29) ? -1900 : -2000;
					break;
					
				case "h":
					theHour24 = strDate.substring(startPos, endPos);
					break;
					
				case "n":
					theMinute = strDate.substring(startPos, endPos);
					break;
					
				case "s":
					theSecond = strDate.substring(startPos, endPos);
					break;
			}//end switch
				
		}//end if this is a code
		
	}//end for
	
	//create a date object using the parts submitted
	//Javascript New Date syntax
	//dateObjectName = new Date(year, month, day, hours, minutes, seconds)
	//this will convert April 31 into May 1 and February 29 into March 1 (if not a leap year)
	var submittedDate = new Date(theYear, theMonth - 1, theDay, theHour24, theMinute, theSecond)

	/*alert("submittedDate.getMonth() - (-1): " + (submittedDate.getMonth() - (-1)) + " == theMonth: " + parseInt(theMonth, 10) + "\n" +
		"submittedDate.getDate(): " + submittedDate.getDate() + " == theDay: " + parseInt(theDay, 10) + "\n" +
		"submittedDate.getFullYear(): " + submittedDate.getFullYear() + " == theYear: " + parseInt(theYear, 10) + "\n" + 
		"submittedDate.getHours(): " + submittedDate.getHours() + " == theHour24: " + parseInt(theHour24, 10) + "\n" +
		"submittedDate.getMinutes(): " + submittedDate.getMinutes() + " == theMinute: " + parseInt(theMinute, 10) + "\n" +
		"submittedDate.getSeconds(): " + submittedDate.getSeconds() + " == theSecond: " + parseInt(theSecond, 10))
	*/
	
	//now if the values extracted from the date object still match the submitted values, the date is valid
	if(
		parseInt(submittedDate.getMonth() - (-1), 10) == parseInt(theMonth, 10) && 
		parseInt(submittedDate.getDate(), 10) == parseInt(theDay, 10) && 
		parseInt(submittedDate.getFullYear(), 10) == parseInt(theYear, 10) && 
		parseInt(submittedDate.getHours(), 10) == parseInt(theHour24, 10) && 
		parseInt(submittedDate.getMinutes(), 10) == parseInt(theMinute, 10) && 
		parseInt(submittedDate.getSeconds(), 10) == parseInt(theSecond, 10)
		)
	{
		return true;
	}
	else
	{
		return false;
	}

}

//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version

function isdate(strDate, strFormat) //as Boolean
{
	return isDate(strDate, strFormat)
}

//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version

function IsDate(strDate, strFormat) //as Boolean
{
	return isDate(strDate, strFormat)
}

//*******************************************************************************'
//add or subtract intervals from a date object
//dtePart has the following values:
// ms = MILLISECONDS
// s = SECONDS
// n = MINUTES
// h = HOURS
// d = DAYS
// m = MONTHS
// y = YEARS

function dateAdd(dtePart, intInterval, objDate) //as Date
{
	//must specify date part and interval
	if (!dtePart || parseInt(intInterval, 10) == 0) return objDate;
	
	//make sure intInterval is of type integer
	intInterval = parseInt(intInterval, 10);
	
	switch(dtePart.toLowerCase())
	{
		case "ms": //MILLISECONDS
			objDate.setMilliseconds(objDate.getMilliseconds() + intInterval);
			break;
		case "s": //SECONDS
			objDate.setSeconds(objDate.getSeconds() + intInterval);
			break;
		case "n": //MINUTES
			objDate.setMinutes(objDate.getMinutes() + intInterval);
			break;
		case "h": //HOURS
			objDate.setHours(objDate.getHours() + intInterval);
			break;
		case "d": //DAYS
			objDate.setDate(objDate.getDate() + intInterval);
			break;
		case "m": //MONTHS
			objDate.setMonth(objDate.getMonth() + intInterval);
			break;
		case "y": //YEARS
			objDate.setFullYear(objDate.getFullYear() + intInterval);
			break;
		default:
			break;
	}
	
	//return the new date
	return objDate;
}

//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version


function  dateadd(interval, number, objDate)
{
	return dateAdd(interval, number, objDate)
}

//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version

function  DateAdd(interval, number, objDate)
{
	return dateAdd(interval, number, objDate)
}

//*******************************************************************************'
//add a new function to the javascript Date() object

Date.prototype.add = function (dtePart, intInterval) //as Date
{
	//save the current date value
	var objDate = this;
	
	return dateAdd(dtePart, intInterval, objDate);
}

//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version

Date.prototype.Add = function (dtePart, intInterval) //as Date
{
	return this.add(dtePart, intInterval)
}

//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version

Date.prototype.dateAdd = function (dtePart, intInterval) //as Date
{
	return this.add(dtePart, intInterval)
}

//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version

Date.prototype.dateadd = function (dtePart, intInterval) //as Date
{
	return this.add(dtePart, intInterval)
}


//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version

Date.prototype.DateAdd = function (dtePart, intInterval) //as Date
{
	return this.add(dtePart, intInterval)
}

/*sample usage
var d = new Date();
var d2 = d.add("d", 3); //+3days
var d3 = d.add("h", -3); //-3hours
alert(d2);
alert(d3);
*/


/*******************************************************************************'
function dateCompare()
parameters: dateString1, dateString2, dateType
returns: integer (-1, 0, 1)
  
dateString1 and dateString2 is a date passed as a string in the following formats:

type 1 : 05/29/1997	(MM/DD/YYYY)
type 2 : 05/29/97		(MM/DD/YY)
type 3 : 29/05/1997	(DD/MM/YYYY)
type 4 : 29/05/97		(DD/MM/YY)
  
dateType is a numeric integer from 1 to 4, representing
the type of dateString passed, as defined above.

Returns -1 if the dateString1 is behind dateString2
Returns 0 if the dateString1 is equal to dateString2 or if dateType is not 1 to 4
Returns 1 if the dateString1 is ahead of dateString2
  
Javascript New Date syntax
1. dateObjectName = new Date()
2. dateObjectName = new Date("month day, year hours:minutes:seconds")
3. dateObjectName = new Date(year, month, day)
4. dateObjectName = new Date(year, month, day, hours, minutes, seconds)

The way JavaScript handles dates is very similar to the way Java handles dates: 
both languages have many of the same date methods, and both store dates internally 
as the number of milliseconds since January 1, 1970 00:00:00. 
Dates prior to 1970 are not allowed.
*/       
 	
function dateCompare(dateString1,dateString2,dateType)
{
	//default the dateType to most common used by me
	if(arguments.length == 2)
		dateType = "1"
		
	switch (dateType.toUpperCase())
	{
		case "MM/DD/YYYY":
		case "1":	// 05/29/1997 (MM/DD/YYYY)
			var myArray = dateString1.split('/');
			var date1 = new Date(myArray[2], myArray[0], myArray[1]);
		
			myArray = dateString2.split("/");
			var date2 = new Date(myArray[2], myArray[0], myArray[1]);
			break;
			
		case "MM/DD/YY":
		case "2": // 05/29/97 (MM/DD/YY)
			var myArray = dateString1.split('/');
			var date1 = new Date((myArray[2] -= (myArray[2] > 29) ? -1900 : -2000), myArray[0], myArray[1]);
		
			myArray = dateString2.split("/");
			var date2 = new Date((myArray[2] -= (myArray[2] > 29) ? -1900 : -2000), myArray[0], myArray[1]);
			break;
	
		case "DD/MM/YYYY":
		case "3":	// 29/05/1997 (DD/MM/YYYY)
			var myArray = dateString1.split('/');
			var date1 = new Date(myArray[2], myArray[1], myArray[0]);
		
			myArray = dateString2.split("/");
			var date2 = new Date(myArray[2], myArray[1], myArray[0]);
			break;
	
		case "DD/MM/YY":
		case "4": // 29/05/97 (DD/MM/YY)
			var myArray = dateString1.split('/');
			var date1 = new Date((myArray[2] -= (myArray[2] > 29) ? -1900 : -2000), myArray[1], myArray[0]);
		
			myArray = dateString2.split("/");
			var date2 = new Date((myArray[2] -= (myArray[2] > 29) ? -1900 : -2000), myArray[1], myArray[0]);
			break;
		
		default:
			alert("Invalid dateType.");
			return false;
	}
	
	//alert("Date 1: " + date1 + "\nDate 2: " + date2)
	
	//if date1 is less than date 2
	if (date1 < date2)
	{
		return -1;
	}
	//if date1 is greater than date 2
	else if (date1 > date2)
	{
		return 1;
	}
	//if date1 is the same as date2
	else
	{
		return 0;
	}
}

//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version

function datecompare(dateString1,dateString2,dateType) //as Integer
{
	return dateCompare(dateString1,dateString2,dateType)
}

//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version

function DateCompare(dateString1,dateString2,dateType) //as Integer
{
	return dateCompare(dateString1,dateString2,dateType)
}

//*******************************************************************************'
//convert a MM/DD/YYYY type date into a date object
//this code is pretty much the same as isDate()
function stringToDate(strDate, strFormat) //as Date
{
	//if strFormat is not passed, default
	if(arguments.length == 1)
	{
		strFormat = "m/d/y";
		//strFormat = "m/d/y/ h:n:s"
	}
	
	//make sure strDate is a string
	strDate = String(strDate);
	
	//remove all A-Z characters save for m,d,y,h,n,s
	strFormat = strFormat.replace(/[abcefgijklopqrtuvwxz]/gi, '');
	
	//replace any double occurances of the codes
	strFormat = strFormat.replace(/([mdyhns])([mdyhns])+/gi,"$1");
	
	//if strFormat is less than / equal to 4 characters it is invalid
	//minimum format is m/d/y = 5 characters
	if(strFormat.length < 5)
	{
		alert("Invalid format. (character count)");
		return false;
	}
	
	//if i do not find 2 or more characters other than A-Z it is invalid
	//there is a minimum of 2 delimeters in m/d/y
	if(strFormat.match(/[^a-z]/gi).length < 2)
	{
		alert("Invalid format. (delimeter count)");
		return false;
	}
	
	//if i find 2 delimeters next to each other it is invalid
	//that's just stupid
	if(strFormat.search(/[^a-z]{2,}/gi) > 0)
	{
		alert("Invalid format. (double delimeter)");
		return false;
	}
	
	//at the end if the syntax test, test for a valid date value
	//i.e. make sure the user is not trying to enter February 31, 2006 or 13/13/2006
	//save each part of a valid date
	var theMonth = 0;
	var theDay = 0;
	var theYear = 0;
	var theHour24 = 0;
	var theMinute = 0;
	var theSecond = 0;

	//create the regular expression string
	var strRegExp = '';
	
	//save which character we are looking at in strFormat
	var chr = '';
	
	//save the delimeter after the code
	var delimiter = '';
	//save the Position if the delimeter in strForamt
	var delimeterPos = -1;
	
	var startPos = -1;
	var endPos = -1;
	
	//for each character in strFormat
	for(var i = 0; i < strFormat.length; i++)
	{
		//get a character
		chr = strFormat.charAt(i);
		
		//if this is a code..
		if(chr.search(/[mdyhns]/) == 0)
		{
			//look forward for the delimeter
			for (var j = i + 1; j < strFormat.length; j++)
			{
				//get the character
				delimeter = strFormat.charAt(j);
				
				//if this character is not m,d,y,h,n,s...
				if(delimeter.search(/[^mdyhns]/) == 0)
				{
					//save the delimeter
					delimeter = strFormat.charAt(j);
					
					//if this delimeter is at the very end of the strFormat, delete it
					if(j == strFormat.length - 1)
						strFormat = strFormat.substring(0, j -1)
					
					//break from this for loop
					break;
				}
			}//end for
			
			//start extrtacting from
			//if the startPos has not been defined, get the position from the current strFormat position
			//else it is 1 character after the last extraction
			startPos = (startPos < 0) ? i : endPos + 1;

			//end position is where the delimeter is or the end of the string
			endPos = ((i + 1) >= strFormat.length) ? strDate.length : strDate.indexOf(delimeter, startPos + 1);
			endPos = (endPos == strDate.length - 1) ? strDate.length : ((endPos == -1) ? strDate.length : endPos);
			
			//alert("startPos: " + startPos + "\nendPos: " + endPos)
			
			//we know which code we are currently looking at and we know the delimeter
			switch (chr)
			{
				case "m":
					theMonth = strDate.substring(startPos, endPos);
					break;
					
				case "d":
					theDay = strDate.substring(startPos, endPos);
					break;
					
				case "y":
					theYear = strDate.substring(startPos, endPos);
					break;
					
				case "h":
					theHour24 = strDate.substring(startPos, endPos);
					break;
					
				case "n":
					theMinute = strDate.substring(startPos, endPos);
					break;
					
				case "s":
					theSecond = strDate.substring(startPos, endPos);
					break;
			}//end switch
				
		}//end if this is a code
		
	}//end for
	
	//create a date object using the parts submitted
	//Javascript New Date syntax
	//dateObjectName = new Date(year, month, day, hours, minutes, seconds)
	//this will convert April 31 into May 1 and February 29 into March 1 (if not a leap year)
	return submittedDate = new Date(theYear, theMonth - 1, theDay, theHour24, theMinute, theSecond)
}

//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version

function stringtodate(strDate, strFormat) //as Date
{
	return stringToDate(strDate, strFormat)
}

//-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -'
//syntax version

function StringToDate(strDate, strFormat) //as Date
{
	return stringToDate(strDate, strFormat)
}

