// DateEx.js - JavaScript Date object extensions
	
// ====================
// === String to date ===
// ====================
// returns:		[Date], parameter String, format: 2010-09-08T00:00:00
	function StringToDate(DateString)
	{
		var intYear = Number(DateString.toString().substring(0, 4));
		var intMonth = Number(DateString.toString().substring(5, 7)) - 1;
		var intDay = Number(DateString.toString().substring(8, 10));
		var intHour = Number(DateString.toString().substring(11, 13));
		var intMinute = Number(DateString.toString().substring(14, 16));
		var intSecond = Number(DateString.toString().substring(17, 19));
		
		return new Date(intYear, intMonth, intDay, intHour, intMinute, intSecond);
	}
	
// ====================
// === String to date2 ===
// ====================
// returns:		[Date], parameter String, format: 06/09/2010 00:00:00
	function StringToDate2(DateString)
	{
		var intYear = Number(DateString.toString().substring(6, 10));
		var intMonth = Number(DateString.toString().substring(3, 5)) - 1;
		var intDay = Number(DateString.toString().substring(0, 2));
		var intHour = Number(DateString.toString().substring(11, 13));
		var intMinute = Number(DateString.toString().substring(14, 16));
		var intSecond = Number(DateString.toString().substring(17, 19));
		
		return new Date(intYear, intMonth, intDay, intHour, intMinute, intSecond);
	}
	
// ====================
// === getDayOfYear ===
// ====================
// returns:			[Integer]	the day of the year (eg Jan 4 would be day 4)
	Date.prototype.getDayOfYear = function()
	{
		// declare local variables
		var dtDate = new Date(this.getFullYear(), 0, 1);
		var lngDayOfYear = this.getDayDifference(dtDate);

		// the result will be a negative value, so convert to positive.
		lngDayOfYear *= -1;

		// increment, as our starting number is 1, rather than 0
		lngDayOfYear++;

		// return the day of the year
		return lngDayOfYear;
	}

// =====================
// === getWeekOfYear ===
// =====================
// returns:			[Integer]	the week number of the year (Week 1 is the week in which Jan 4 occurs. Week is Sun-Sat)
	Date.prototype.getWeekOfYear = function()
	{	
		// declare local variables
		var dtDate = new Date(this.getFullYear(), 0 , 1);
		var lngDay = dtDate.getDay();
		if(lngDay == 0)
		{
			lngDay = 7;
		}

		var lngDifference = 0;
		var lngWeekNo = 1;

		// crank the day back to the beginning of the week
		dtDate.setDate((lngDay * -1) + 1);

		// get the number of days
		lngDifference = this.getDayDifference(dtDate) * -1;
		
		// decrement as days are 1-based, not 0-based
		lngDifference--;

		// divide by seven to get the number of weeks
		lngDifference /= 7;

		// get the integer part and increment (as week numbers are 1-based not 0-based)
		lngWeekNo = parseInt(lngDifference, 10) + 1;

		// if the first day of the year is on friday or later, add an extra week
//		if(lngDay > 3)
//		{
//			lngWeekNo -= 1;
//		}

		// return the week number
		return lngWeekNo;
	}

// =====================
// === getDifference ===
// =====================
// in: strInterval	[String]	the interval to which the difference is calculated, valid values for strInterval are, 
//								'ms' - milliseconds
//								's'  - seconds
//								'mn' - minutes
//								'h'  - hours
//								'd'  - days (hrs, mins, secs and msecs are ignored)
//								'w'  - weeks (7-day unit)
//								'ww' - weeks (by week number)
//								'm'  - months (days are ignored)
//								'y'  - years (months are ignored)
//								Any other value causes the function to return null.
//
// in: dtDate		[Date]		the date with which, we wish to calculate the difference.
//
// returns:			[Integer]	the difference, in the number of intervals as specified by strInterval, between 
//								dtDate and this Date object, or null if the calculation could not be performed.
	Date.prototype.getDifference = function getDifference(strInterval, dtDate)
	{
		// validate the incoming parameters
		if(strInterval.constructor != String)
		{
			return null;
		}

		if(dtDate.constructor != Date)
		{
			return null;
		}

		// declare local variables
		var lngDifference = 0;
		var regExp = /\s/;
		
		// trim the interval parameter and convert to lower case
		strInterval = strInterval.replace(regExp, "");
		strInterval = strInterval.toLowerCase();
		
		// test the interval parameter to see what interval we wish to use
		switch(strInterval)
		{	
			// milliseconds
			case "ms"	:	lngDifference = this.getMillisecondsDifference(dtDate);
							break;

			// seconds
			case "s"	:	lngDifference = this.getSecondsDifference(dtDate);
							break;

			// minutes
			case "mn"	:	lngDifference = this.getMinutesDifference(dtDate);
							break;

			// hours
			case "h"	:	lngDifference = this.getHoursDifference(dtDate);
							break;

			// days
			case "d"	:	lngDifference = this.getDayDifference(dtDate);
							break;
			
			// weeks
			case "w"	:	lngDifference = this.getWeekDifference(dtDate);
							break;
			
			// weeks (by week no)
			case "ww"	:	lngDifference = this.getWeekNoDifference(dtDate);
							break;

			// months
			case "m"	:	lngDifference = this.getMonthDifference(dtDate);
							break;
			
			// years
			case "y"	:	lngDifference = this.getYearDifference(dtDate);
							break;
			
			// unknown
			default		:	lngDifference = null;
		}
		
		// return the difference
		return lngDifference;
	}

// =================================
// === getMillisecondsDifference ===
// =================================
// in: dtDate		[Date]		the date with which, we wish to calculate the difference.
//
// returns:			[Integer]	the difference, in milliseconds, between dtDate and this Date object,
//								or null if the calculation could not be performed.
	Date.prototype.getMillisecondsDifference = function(dtDate)
	{
		// check the incoming date parameter
		if(dtDate.constructor != Date)
		{
			return null;
		}

		// declare local variables and calculate the difference
		var lngDifference = Date.parse(dtDate) - Date.parse(this);

		// return the difference
		return parseInt(lngDifference, 10);
	}

// ============================
// === getSecondsDifference ===
// ============================
// in: dtDate		[Date]		the date with which, we wish to calculate the difference.
//
// returns:			[Integer]	the difference, in seconds, between dtDate and this Date object,
//								or null if the calculation could not be performed.
	Date.prototype.getSecondsDifference = function(dtDate)
	{
		// check the incoming date parameter
		if(dtDate.constructor != Date)
		{
			return null;
		}

		// declare local variables and calculate the difference
		var lngDifference = Date.parse(dtDate) - Date.parse(this);

		// now divide by 1000 to get the seconds
		lngDifference /= 1000;

		// return the difference
		return parseInt(lngDifference, 10);
	}

// ============================
// === getMinutesDifference ===
// ============================
// in: dtDate		[Date]		the date with which, we wish to calculate the difference.
//
// returns:			[Integer]	the difference, in minutes, between dtDate and this Date object,
//								or null if the calculation could not be performed.
	Date.prototype.getMinutesDifference = function(dtDate)
	{
		if(dtDate.constructor != Date)
		{
			return null;
		}

		// declare local variables and calculate the difference
		var lngDifference = Date.parse(dtDate) - Date.parse(this);

		// now divide by (1000 * 60) to get the minutes
		lngDifference /= (1000 * 60);

		// return the difference
		return parseInt(lngDifference, 10);
	}

// ==========================
// === getHoursDifference ===
// ==========================
// in: dtDate		[Date]		the date with which, we wish to calculate the difference.
//
// returns:			[Integer]	the difference, in hours, between dtDate and this Date object,
//								or null if the calculation could not be performed.
	Date.prototype.getHoursDifference = function(dtDate)
	{
		if(dtDate.constructor != Date)
		{
			return null;
		}

		// declare local variables and calculate the difference
		var lngDifference = Date.parse(dtDate) - Date.parse(this);

		// now divide by (1000 * 60 * 60) to get the hours
		lngDifference /= (1000 * 60 * 60);

		// return the difference
		return parseInt(lngDifference, 10);
	}

// ========================
// === getDayDifference ===
// ========================
// in: dtDate		[Date]		the date with which, we wish to calculate the difference.
//
// returns:			[Integer]	the difference, in days, between dtDate and this Date object,
//								or null if the calculation could not be performed.
	Date.prototype.getDayDifference = function(dtDate)
	{
		// check our incoming date parameter
		if(dtDate.constructor != Date)
		{
			return null;
		}

		// declare local variables
		var lngDifference = 0;
		var dtDate1 = new Date(this.getFullYear(), this.getMonth(), this.getDate());
		var dtDate2 = new Date(dtDate.getFullYear(), dtDate.getMonth(), dtDate.getDate());
		
		// calculate the difference in milliseconds
		lngDifference = Date.parse(dtDate2) - Date.parse(dtDate1);
		
		// now divide to convert milliseconds into days
		lngDifference /= (1000 * 60 * 60 * 24);
		
		// return the difference
		return parseInt(lngDifference, 10);
	}

// =========================
// === getWeekDifference ===
// =========================
// in: dtDate		[Date]		the date with which, we wish to calculate the difference.
//
// returns:			[Integer]	the difference, in weeks(7-day units), between dtDate and this Date object,
//								or null if the calculation could not be performed.
	Date.prototype.getWeekDifference = function(dtDate)
	{
		// check our incoming date parameter
		if(dtDate.constructor != Date)
		{
			return null;
		}

		// declare local variables
		var lngDifference = this.getDayDifference(dtDate);
		
		// now divide to convert days into weeks
		lngDifference /= 7;
		
		// return the difference
		return parseInt(lngDifference, 10);
	}

// ===========================
// === getWeekNoDifference ===
// ===========================
// in: dtDate		[Date]		the date with which, we wish to calculate the difference.
//
// returns:			[Integer]	the difference, in weeks(by week number), between dtDate and this Date object,
//								or null if the calculation could not be performed.
	Date.prototype.getWeekNoDifference = function(dtDate)
	{
		// check our incoming date parameter
		if(dtDate.constructor != Date)
		{
			return null;
		}

		// declare local variables
		var lngDifference = dtDate.getWeekOfYear() - this.getWeekOfYear();

		// return the difference
		return lngDifference;
	}

// ==========================
// === getMonthDifference ===
// ==========================
// in: dtDate		[Date]		the date with which, we wish to calculate the difference.
//
// returns:			[Integer]	the difference, in months, between dtDate and this Date object,
//								or null if the calculation could not be performed.
	Date.prototype.getMonthDifference = function(dtDate)
	{
		// declare local variables
		var lngDifference	= 0;
		var lngYearDiff		= 0;
		var lngMonthDiff	= 0;
		
		// check our incoming date parameter
		if(dtDate.constructor != Date)
		{
			return null;
		}
		
		// calculate the difference between the year part of the dates
		lngYearDiff = this.getYearDifference(dtDate);

		// calculate the difference between the month part of the dates
		lngMonthDiff = dtDate.getMonth() - this.getMonth();
		
		// calculate the difference in months, between the dates
		lngDifference = (lngYearDiff * 12) + lngMonthDiff;
		
		// return the difference
		return parseInt(lngDifference, 10);
	}

// =========================
// === getYearDifference ===
// =========================
// in: dtDate		[Date]		the date with which, we wish to calculate the difference.
//
// returns:			[Integer]	the difference, in years, between dtDate and this Date object,
//								or null if the calculation could not be performed.
	Date.prototype.getYearDifference = function(dtDate)
	{
		// check our incoming date parameter
		if(dtDate.constructor != Date)
		{
			return null;
		}
	
		// calculate the difference between the year part of the dates
		lngDifference = dtDate.getFullYear() - this.getFullYear();
		
		// return the difference
		return parseInt(lngDifference, 10);
	}

// ====================
// === getMonthName ===
// ====================
// returns:			[String]	the name of the month stored in this Date object, or null if the month value
//								is not valid.
	Date.prototype.getMonthName = function()
	{
		// declare local variables
		var strMonthName;

		// which month name do we want?
		switch(this.getMonth())
		{
			case 0	:	strMonthName = "January";
						break;
			
			case 1	:	strMonthName = "February";
						break;

			case 2	:	strMonthName = "March";
						break;

			case 3	:	strMonthName = "April";
						break;

			case 4	:	strMonthName = "May";
						break;

			case 5	:	strMonthName = "June";
						break;
			
			case 6	:	strMonthName = "July";
						break;
			
			case 7	:	strMonthName = "August";
						break;

			case 8	:	strMonthName = "September";
						break;

			case 9	:	strMonthName = "October";
						break;

			case 10	:	strMonthName = "November";
						break;

			case 11	:	strMonthName = "December";
						break;

			default	:	strMonthName = null;
		}
		
		// return the month name
		return strMonthName;
	}

// ======================
// === getWeekdayName ===
// ======================
// returns:			[String]	the name of the weekday stored in this Date object, or null 
//								if the weekday value is not valid.
	Date.prototype.getWeekdayName = function()
	{		
		// declare local variables
		var strWeekdayName;

		// which weekday name do we want?
		switch(this.getDay())
		{
			case 0	:	strWeekdayName = "Sunday";
						break;

			case 1	:	strWeekdayName = "Monday";
						break;

			case 2	:	strWeekdayName = "Tuesday";
						break;

			case 3	:	strWeekdayName = "Wednesday";
						break;

			case 4	:	strWeekdayName = "Thursday";
						break;

			case 5	:	strWeekdayName = "Friday";
						break;

			case 6	:	strWeekdayName = "Saturday";
						break;

			default	:	strWeekdayName = null;
		}
		
		// return the weekday name
		return strWeekdayName;
	}

// =====================
// === getDateSuffix ===
// =====================
// returns:			[String]	the suffix, i.e. "st", "nd", "rd", "th" of the day part of this Date object.
	Date.prototype.getDateSuffix = function()
	{
		// declare local variables
		var strSuffix;
		
		// which day of the month is it?
		switch(this.getDate())
		{
			case 1	:
			case 21	:
			case 31	:	strSuffix = "st";
						break;
			
			case 2	:
			case 22	:	strSuffix = "nd";
						break;

			case 3	:
			case 23 :	strSuffix = "rd";
						break;

			default	:	strSuffix = "th";
		}
		
		// return the suffix
		return strSuffix;
	}

// ===================
// === getLongDate ===
// ===================
// returns:			[String]	the long string format representation of the Date - eg "Monday 1st January, 2002"
	Date.prototype.getLongDate = function()
	{
		// declare local variables
		var strDate;

		// build the long date
		strDate = this.getWeekdayName() + " " + this.getDate().toString() + this.getDateSuffix() + " " + this.getMonthName() + ", " + this.getFullYear().toString();

		return strDate;
	}
	
// ===================
// === getLongDateSimple ===
// ===================
// returns:			[String]	the long string format representation of the Date - eg "1 January 2002"
	Date.prototype.getLongDateSimple = function()
	{
		// declare local variables
		var strDate;

		// build the long date
		strDate = this.getDate().toString() + " " + this.getMonthName() + " " + this.getFullYear().toString();

		return strDate;
	}
	
// ===================
// === getLongDateSimpleWithSuffix ===
// ===================
// returns:			[String]	the long string format representation of the Date - eg "1st January 2002"
	Date.prototype.getLongDateSimpleWithSuffix = function()
	{
		// declare local variables
		var strDate;

		// build the long date
		strDate = this.getDate().toString() + this.getDateSuffix() + " " + this.getMonthName() + " " + this.getFullYear().toString();

		return strDate;
	}

// ====================
// === getShortDate ===
// ====================
// returns			[String]	the short string format representation of the Date as dd/mm/yyyy
//								eg "01/01/2001"
	Date.prototype.getShortDate = function()
	{
		// declare local variables
		var strDay = this.getDate().toString();
		var strMonth = (this.getMonth() + 1).toString();
		var strYear = this.getFullYear().toString();

		// check if the day needs a leading zero
		if(strDay.length < 2)
		{
			strDay = "0" + strDay;
		}

		// check if the month needs a leading zero
		if(strMonth.length < 2)
		{
			strMonth = "0" + strMonth;
		}

		// return the short date
		return strDay + "/" + strMonth + "/" + strYear;
	}

// ======================
// === getDaysInMonth ===
// ======================
// returns			[Integer]	the number of days in the month of the Date object (28, 29, 30, 31)
	Date.prototype.getDaysInMonth = function()
	{
		// declare local variables
		var dtDate1 = new Date(this.getFullYear(), this.getMonth(), 1);
		var dtDate2 = new Date(this.getFullYear(), this.getMonth(), 1);
		var lngDifference = 0;
		
		// add one month to the second date
		dtDate2.setMonth(dtDate1.getMonth() + 1);

		// now get the difference
		lngDifference = dtDate1.getDifference("d", dtDate2);

		// return the number of days
		return lngDifference;
	}

// ==========================
// === getFirstDayOfMonth ===
// ==========================
// returns			[Integer]	the enumerated value for the day of the week the first day of the month
//								of this Date object falls on.
	Date.prototype.getFirstDayOfMonth = function()
	{
		// declare local variables
		dtDate = new Date(this.getFullYear(), this.getMonth(), 1);

		// return the weekday
		return dtDate.getDay();
	}

// ===============
// === dateAdd ===
// ===============
// in: strInterval	[String]	the interval we wish to add to the date, valid values for strInterval are, 
//								'ms' - milliseconds
//								's'  - seconds
//								'mn' - minutes
//								'h'  - hours
//								'd'  - days 
//								'w'  - weeks (7-day unit)
//								'm'  - months 
//								'y'  - years 
//
//	in:	lngNumber	[Integer]	the number of intervals to add to the date
//	
//	returns:		[Boolean]	indicates success or failure of the method.
	Date.prototype.dateAdd = function(strInterval, lngNumber)
	{
		// validate the incoming parameters
		if(strInterval.constructor != String)
		{
			return false;
		}

		if(lngNumber.constructor != Number)
		{
			return false;
		}

		// declare local variables
		var regExp = /\s/;
		
		// trim the interval parameter and convert to lower case
		strInterval = strInterval.replace(regExp, "");
		strInterval = strInterval.toLowerCase();
		
		// test the interval parameter to see what interval we wish to use
		switch(strInterval)
		{	
			// milliseconds
			case "ms"	:	this.setMilliseconds(this.getMilliseconds() + lngNumber);
							break;

			// seconds
			case "s"	:	this.setSeconds(this.getSeconds() + lngNumber);
							break;

			// minutes
			case "mn"	:	this.setMinutes(this.getMinutes() + lngNumber);
							break;

			// hours
			case "h"	:	this.setHours(this.getHours() + lngNumber);
							break;

			// days
			case "d"	:	this.setDate(this.getDate() + lngNumber);
							break;
			
			// weeks
			case "w"	:	this.setDate(this.getDate() + (lngNumber * 7))
							break;
			
			// months
			case "m"	:	this.setMonth(this.getMonth() + lngNumber)
							break;
			
			// years
			case "y"	:	this.setYear(this.getFullYear() + lngNumber)
							break;
			
			// unknown
			default		:	return false;
		}
		
		// return success
		return true; 
	}
