// Copyright (C) 2007 Cognos Incorporated. All rights reserved.
// Cognos (R) is a trademark of Cognos Incorporated.

/*
CDatePickerCommon.js

This script provides utility functions for the date and dateTime
prompt controls
*/

//global variable
var g_dNow = new Date();

//get the current date
//default to today's date
var curYear = g_dNow.getFullYear();
var curMonth = g_dNow.getMonth();
var curDay = g_dNow.getDate();

//return a formatted text string based on a given day
function getFormatDate(dSetDay, iType, sInputOrder)
{
	if (!dSetDay)
	{
		return false;
	}

	var displayDay = dSetDay.getDate();

	//locale medium format
	var yearFormat = g_yearFormatMedium;
	var monthFormat = g_monthFormatMedium;
	var dayFormat = g_dayFormatMedium;
	var sep = g_dateSeparatorMedium;

	var sYear ="";
	var sY = "";
	var sM = "";
	var sD = "";

	//0 = standard ; 1 = japaneseEmperor
	if (iType == 1)
	{
		sY = getJapaneseEra(dSetDay);
	}
	else
	{
		sY = dSetDay.getFullYear();
		sY = "0000" + sY;
		sY = sY.substring(sY.length-4, sY.length);

		//show as two digit year for those locales that require it
		if ((yearFormat == "yy") && (parseInt(sY, 10) > 1900))
		{
			sY = sY.substring(sY.length-2, sY.length);
		}
	}

	//get the formatted month
	if (monthFormat == "M")
	{
		sM = dSetDay.getMonth() + 1;
	}
	else if (monthFormat == "MMM")
	{
		sM = g_arMonthsAbbr[dSetDay.getMonth()];
	}
	else if (monthFormat == "MMMM")
	{
		sM = g_arMonths[dSetDay.getMonth()];
	}
	else
	{
		var iM = dSetDay.getMonth() + 1;

		sM = iM.toString();
		if (sM.length == 1)
		{
			sM = "0" + sM;
		}
	}

	if (dayFormat.match(/DD/i))
	{
		var iD = dSetDay.getDate();
		sD = iD.toString();
		if (sD.length == 1)
		{
			sD = "0" + sD;
		}

	}
	else
	{
		sD = dSetDay.getDate();
	}

	// show in medium date format
	// strip out the time part of the format string
	var reTimestamp = new RegExp("(" + g_timeSeparator + "*" + g_hourFormatMedium + g_timeSeparator + "*" + "|" + g_timeSeparator + "*" + g_minuteFormatMedium + g_timeSeparator + "*" + "|" + g_timeSeparator + "*" + g_secondFormatMedium + g_timeSeparator + "*" + "|a" + ")", "g");
	var sFormatDate = g_mediumFormat.replace(reTimestamp,"").replace(/^\s+|\s+$/,"");

	sFormatDate = sFormatDate.replace(RegExp(yearFormat, "g"), sY);
	sFormatDate = sFormatDate.replace(RegExp(dayFormat, "g"), sD);
	sFormatDate = sFormatDate.replace(RegExp(monthFormat, "g"), sM);

	return sFormatDate;
}

//return the number of days in the month
function intGetDays(intMonth, intYear)
{
	switch (intMonth)
	{
		case 0:
			return 31; // jan
		case 1:
			return (boolLeapYear(intYear))? 29:28; //feb
		case 2:
			return 31; //mar
		case 3:
			return 30;//apr
		case 4:
			return 31;//may
		case 5:
			return 30;//jun
		case 6:
			return 31;//jul
		case 7:
			return 31;//aug
		case 8:
			return 30;//sep
		case 9:
			return 31;//oct
		case 10:
			return 30;//nov
		case 11:
			return 31;//dec
		default:
			return -1; //problem determining month
	}
}

//return the text for a given month
function sGetMonth(iMonth)
{
	return g_arMonthsAbbr[iMonth];
}

//return the text for a given day
function sGetDay(iDay)
{
	return g_arDaysAbbr[iDay];
}


//check to see if this is a leap year
/*if divisible evenly by 4, a Gregorian year is a leap year, with a February 29 and 366 days
 (e.g. 1996/4 = 499, so 1996 is a leap year), UNLESS
 if divisible evenly by 100, a Gregorian year is a normal year with 365 days
 (e.g.1900/100=19, so 1900 is a normal year of 365 days), UNLESS
 if divisible evenly by 400, a Gregorian year is a leap year;
 so the year 2000 is a leap year.
*/
function boolLeapYear(iYear)
{

	if ((iYear % 4 === 0) && ( (!(iYear % 100 === 0)) || (iYear % 400 === 0) ) )
	{
		return true;
	}
	else
	{
		return false;
	}

}

//return true if a string is a valid year
function boolTestYear(sTestYear)
{
	if (sTestYear.length > 4)
	{
		//currently year 10000 and above not supported
		//in date object
		return false;
	}

	var i;

	// Search through string's characters one by one
	// until we find a non-numeric character.
	// When we do, return false; if we don't, return true.

	for (i = 0; i < sTestYear.length; i++)
	{
		// Check that current character is number.
		var sTestChar = sTestYear.charAt(i);
		if (!boolTestDigit(sTestChar))
		{
			return false;
		}
	}

	// All characters are numbers.
	return true;
}

// Returns true if character sTestChar is a digit
// (0 .. 9).
function boolTestDigit (sTestChar)
{
	return ((sTestChar >= "0") && (sTestChar <= "9"));
}

//use this function to see if a string
//can be turned into a valid date
function boolTestDate(sTestDate)
{
	var dTestDate = Date.parse(sTestDate);
	if (dTestDate) //this is a valid date
	{
		return true;
	}
	else
	{
		return false;
	}
}

//TODO
function boolTestDateValidity(mdate)
{
	if (mdate.getTime()) //this is a valid date
	{
		return true;
	}
	else
	{
		return false;
	}
}

//remove non alpha numeric data from a string
function sStripNonAlphanumerics(sString)
{
	var charDelimiters = /[ ,-]/g;
	var arTestDateStrip = sString.split(charDelimiters);
	var sTestDateStrip = arTestDateStrip.join(" ");

	return sTestDateStrip;
}

//parse string input and return a date object
//return false if the value is not a date
//if the input order is supplied, the parser
//can determine ambiguous dates

//ToDo: handle japanese days e.g. do any of the strings start with numbers, strip out day characters
//ToDo: handle imperial time strings (this may need to happen prior to launching this function
function dParseDate(sTestDate, sInputOrder)
{
	//////////////////////
	// this logic should be able to properly parse any of the following typed in values
	//
	//	jan 01 2001
	//	june/05-2002
	//	29-MAY-1999
	//	01/02/2002	(requires inputOrder)
	//	2002-02-10	(requires inputOrder)
	//	2002/Feb/28

	//declare variables
	var iMonth = null;
	var iDay = null;
	var iYear = null;
	var arMonthNames;

	bFoundDay = false;
	iDayPos = null;
	bFoundMonth = false;
	iMonthPos = null;
	bFoundYear = false;
	iYearPos = null;

	//determine input order from locale
	//declare variables and default to international standard YMD
	var iYearExpectedPos = 0;
	var iMonthExpectedPos = 1;
	var iDayExpectedPos = 2;

	var rNoIntegers = /[^0-9]/;
	var myTestDate = null;

	//get the input order
	if (sInputOrder)
	{
		switch(sInputOrder)
		{
			case "MYD":
				iYearExpectedPos=1;
				iMonthExpectedPos=0;
				iDayExpectedPos=2;
				break;
			case "MDY":
				iYearExpectedPos=2;
				iMonthExpectedPos=0;
				iDayExpectedPos=1;
				break;
			case "YMD":
				iYearExpectedPos=0;
				iMonthExpectedPos=1;
				iDayExpectedPos=2;
				break;
			case "YDM":
				iYearExpectedPos=0;
				iMonthExpectedPos=2;
				iDayExpectedPos=1;
				break;
			case "DMY":
				iYearExpectedPos=2;
				iMonthExpectedPos=1;
				iDayExpectedPos=0;
				break;
			case "DYM":
				iYearExpectedPos=1;
				iMonthExpectedPos=2;
				iDayExpectedPos=0;
				break;
			default:
				iYearExpectedPos=0;
				iMonthExpectedPos=1;
				iDayExpectedPos=2;
				break;
		}
	}

	//strip out any extraneous characters
	//pass 1 (strip out the medium and short delimiters)
	var sTestDateReplace = sTestDate;
	var specialCharacters = "?.[]^$(){}|\\&";
	var dateSepShort = specialCharacters.indexOf(g_dateSeparatorShort) >= 0 ? ("\\" + g_dateSeparatorShort) : g_dateSeparatorShort;
	var rShortDateDelimiter = new RegExp(dateSepShort, "g");
	sTestDateReplace = sTestDateReplace.replace(rShortDateDelimiter, " ");

	var dateSepMedium = specialCharacters.indexOf(g_dateSeparatorMedium) >= 0 ? ("\\" + g_dateSeparatorMedium) : g_dateSeparatorMedium;
	var rMediumDateDelimiter = new RegExp(dateSepMedium, "g");
	sTestDateReplace = sTestDateReplace.replace(rMediumDateDelimiter, " ");

	//pass 2 (strip out other known delimiters)
	var rDelimiters = /[ ,\-\/\\#\:]/g;

	//split the string into tokens
	var arDateTokens = sTestDateReplace.split(rDelimiters);

	//do we have enough tokens to proceed?
	if (arDateTokens.length != 3)
	{
		var rDelimitersWithDecimal = /[ ,\.\-\/\\#\:]/g;
		arDateTokens = sTestDateReplace.split(rDelimitersWithDecimal);
	}

	//check to see if there are enough tokens. (we need 3)
	if (arDateTokens.length < 3)
	{
		// we have less than three tokens,
		// the date is not valid
		return false;
	}

	else if (arDateTokens.length > 3)
	{
		//remove any empty array items
		//NS7 will create empty array items
		var arCleanArray = new Array();
		for (var x=0; x < arDateTokens.length; x++)
		{
			if (arDateTokens[x] !== '')
			{
				arCleanArray = arCleanArray.concat(arDateTokens[x]);
			}
		}
		//use the stripped array
		arDateTokens = arCleanArray;
	}

	if (arDateTokens.length > 3)
	{
		//we have more than three tokens
		//remove any character data and try again
		//this could be because of locale
		//for example, Japanese dates include symbols
		//strip any tokens with alpha numeric characters from the array of tokens
		var arStrippedArray = new Array();
		for (var i=0; i < arDateTokens.length; i++)
		{
			var z = arDateTokens[i].search(rNoIntegers);
			if (z == -1)
			{
				if (arDateTokens[i])
				{
					arStrippedArray = arStrippedArray.concat(arDateTokens[i]);
				}
			}
		}

		//check again
		//do we have 3 characters? if not error
		if (arStrippedArray.length == 3)
		{
			//use the stripped array
			arDateTokens = arStrippedArray;
		}
		else
		{
			//there is an incorrect number of tokens
			return false;
		}
	}

	//try to match the tokens according to input order
	//try and match year (medium and short formats)
	//what is the year position?
	if (arDateTokens[iYearExpectedPos].search(rNoIntegers) == -1)
	{
		if ((arDateTokens[iYearExpectedPos].length >= 1) && (arDateTokens[iYearExpectedPos].length <= 4))
		{
			iYear = arDateTokens[iYearExpectedPos];
			if (iYear.length == 2)
			{
				iYear = sShortToFullYearConversion(iYear);
			}

			bFoundYear = true;
			iYearPos= iYearExpectedPos;
		}
	}

	//try and match month (medium and short formats)
	//see if it matches the a localized month
	var sTestMonth = false;
	var iTestMonth = false;

	if (bNumbersOnly(arDateTokens[iMonthExpectedPos]) === true)
	{
		iTestMonth = parseInt(arDateTokens[iMonthExpectedPos],10) - 1;
	}
	else
	{
		sTestMonth = iCheckMonthString(arDateTokens[iMonthExpectedPos]);
	}

	if ((parseInt(sTestMonth,10) >= 0) && (parseInt(sTestMonth,10) <= 11))
	{
		iMonth = sTestMonth;
		bFoundMonth = true;
		iMonthPos = iMonthExpectedPos;
	}
	//see if it is a valid month by number
	else if (checkMonth(iTestMonth))
	{
		iMonth = iTestMonth;
		bFoundMonth = true;
		iMonthPos = iMonthExpectedPos;
	}

	//try and match day
	//we need a valid year and month to do this
	if ((bFoundMonth) && (bFoundYear))
	{
		if (checkDay(arDateTokens[iDayExpectedPos], parseInt(iMonth, 10), parseInt(iYear, 10)))
		{
			iDay = arDateTokens[iDayExpectedPos];
			bFoundDay = true;
			iDayPos = iDayExpectedPos;
		}
	}

	// do we have a valid date
	// if yes, update date
	if ((bFoundMonth) && (bFoundYear) && (bFoundDay))
	{
		// everything looks good, so use the javascript Date object to return a day
		myTestDate = new Date (iYear, iMonth, iDay);
		//set the year 'full' year explicitly
		myTestDate.setFullYear(iYear);

		if (!boolTestDateValidity(myTestDate))
		{
			//check on the date failed, return false
			return false;
		}
		else
		{
			//got a valid date, return it to the user
			return myTestDate;
		}
	}

	//The input did not match the locale's input order
	//perform a deeper analysis of the input
	bFoundYear = false;
	bFoundMonth = false;
	bFoundDay = false;
	iYear = null;
	iMonth = null;
	iDay = null;

	//try to match against SQL format
	iYearExpectedPos=0;
	iMonthExpectedPos=1;
	iDayExpectedPos=2;

	iYear = arDateTokens[0];

	iMonth = parseInt(arDateTokens[1],10)-1;
	iDay = parseInt(arDateTokens[2],10);

	//match year
	if ((bCheckFullYear(iYear)) && (checkMonth(iMonth)) && checkDay(iDay, iMonth, parseInt(iYear,10)))
	{
		myTestDate = new Date (iYear, iMonth, iDay);
		//set the year 'full' year explicitly
		myTestDate.setFullYear(iYear);
		return myTestDate;
	}

	//look for landmarks (such as a string month name or 4 digit year)
	//try to find the month (match against medium format) by string
	iYear = null;
	iMonth = null;
	iDay = null;

	var k=0;
	for (k=0; k < arDateTokens.length; k++)
	{
		var sSearchMonth = iCheckMonthString(arDateTokens[k]);

		if ((parseInt(sSearchMonth, 10) >= 0) && (parseInt(sSearchMonth, 10) <= 11))
		{
			iMonth = parseInt(sSearchMonth, 10);
			bFoundMonth = true;
			iMonthPos = k;
		}
	}

	//try to find the year (match 3 or 4 digits)
	var l=0;
	for (l=0; l < arDateTokens.length; l++)
	{
		if (bCheckFullYear(arDateTokens[l]) === true)
		{
			iYear= arDateTokens[l];
			bFoundYear = true;
			iYearPos = l;
		}
	}

	//do we have a month and year?  try to assign day
	//found the year and month -- can we nail the day??
	if ((bFoundYear) && (bFoundMonth))
	{
		//grab the day
		var m = 0;
		for (m=0; m < arDateTokens.length; m++)
		{
			if ((m != iYearPos) && (m != iMonthPos))
			{
				if (arDateTokens[m].search(rNoIntegers) == -1)
				{
					//is this a valid day?
					if (checkDay(arDateTokens[m], parseInt(iMonth,10), parseInt(iYear,10)))
					{

						iDay = arDateTokens[m];
						bFoundDay = true;
						iDayPos= m;
					}
				}
			}
		}
	}

	// do we have a valid date
	// if yes, update date
	if ((bFoundMonth) && (bFoundYear) && (bFoundDay))
	{
		// everything looks good, so use the javascript Date object to return a day
		myTestDate = new Date (iYear, iMonth, iDay);
		//set the year 'full' year explicitly
		myTestDate.setFullYear(iYear);

		if (!boolTestDate(myTestDate))
		{
			//this is not a valid date, return false
			return false;
		}
		else
		{
			//got a valid date, return it to the user
			return myTestDate;
		}
	}
	else
	{
		// if no, error
		return false;
	}
}

//test to see if a string is a year
function bCheckFullYear(sTestYear)
{
	var rNoIntegers = /[^0-9]/;
	var z = sTestYear.search(rNoIntegers);
	if (z == -1)
	{
		if ((sTestYear.length == 3) || (sTestYear.length == 4))
		{
			return true;
		}
	}
	return false;
}

//check to see if a string is a month
function iCheckMonthString(sTestMonth)
{
	//make the test month name the same size or smaller than the month
	//find the first match
	var j=0;
	for (j=0; j<g_arMonthsAbbr.length; j++)
	{
		//some locales use an optional '.' in the abbreviation
		//strip any periods off
		var rPeriod = new RegExp("\\.", "gi");
		var sMonthCompare = g_arMonthsAbbr[j];
		sMonthCompare = sMonthCompare.replace(rPeriod,"");
		var iMonthLength = sMonthCompare.length;


		var sTestMonthTest = null;
		if (sTestMonth.length > iMonthLength)
		{
			sTestMonthTest = sTestMonth.substr(0, iMonthLength);
		}
		else
		{
			sTestMonthTest = sTestMonth;
		}

		//strip periods
		sTestMonthTest = sTestMonthTest.replace(rPeriod, "");

		var myPattern = new RegExp("^" + sTestMonthTest, "i"); //ignore case
		//is there a match?
		if (sMonthCompare.match(myPattern))
		{
			//found a month, return it
			return j;
		}
	}
	return false;
}

//check month from a string
function checkMonth(s)
{
 	var num = parseInt (s,10);
	if ((num >= 0) && (num <= 11))
	{
		return true;
	}
	else
	{
		return false;
	}
}

//check the number of days in the month
function checkDay(s, iTestMonth, iTestYear)
{
	var iMaxDays = intGetDays(iTestMonth, iTestYear);
	var num = parseInt(s,10);
	return ((num >= 1) && (num <= iMaxDays));
}

function bIsDateLater(dDate, dTestDate)
{
	//remove the time portions
	dDate.setHours(0);
	dDate.setSeconds(0);
	dDate.setMinutes(0);
	dDate.setMilliseconds(0);
	dTestDate.setHours(0);
	dTestDate.setSeconds(0);
	dTestDate.setMinutes(0);
	dTestDate.setMilliseconds(0);

	if (dDate > dTestDate)
	{
		return true;
	}
	else
	{
		return false;
	}
}

function bIsDateEarlier(dDate, dTestDate)
{
	//remove the time portions
	dDate.setHours(0);
	dDate.setSeconds(0);
	dDate.setMinutes(0);
	dDate.setMilliseconds(0);
	dTestDate.setHours(0);
	dTestDate.setSeconds(0);
	dTestDate.setMinutes(0);
	dTestDate.setMilliseconds(0);

	if (dDate < dTestDate)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//determine if a string has only numbers in it
function bNumbersOnly(s)
{
	var rNoIntegers = /[^0-9]/;
	var z = s.search(rNoIntegers);
	if (z == -1)
	{
		return true;
	}
	else
	{
		return false;
	}

}
//japanese emperor time functions

//create a japanese era object
//	sName: the name of the era
//	sStartYear: beginning year of the era
// 	sStartMonth: beginning month of the era
// 	sStartDay: beginning day of the era
//	sEndYear: end year of the era
// 	sEndMonth: end month of the era
//	sEndDay: end day of the era
function japaneseEra (sName, sStartYear, sStartMonth, sStartDay, sEndYear, sEndMonth, sEndDay)
{
	this.m_sName = sName;
	this.m_dStartDate = new Date(sStartYear,  (parseInt(sStartMonth,10) -1).toString(), sStartDay, 0,0,0 );
	this.m_dEndDate = new Date(sEndYear, (parseInt(sEndMonth,10) -1).toString(), sEndDay, 23, 59, 59);
}

//return the japanese era from a date
function getJapaneseEra (dTestDate)
{
	var sJapaneseEra = "";
	for (i=0; i < japaneseEras.length; i++)
	{
		if (dTestDate >= japaneseEras[i].m_dStartDate && dTestDate <= japaneseEras[i].m_dEndDate)
		{
			sJapaneseEra = japaneseEras[i].m_sName;
			var eraYear = (parseInt(dTestDate.getFullYear()) - parseInt(japaneseEras[i].m_dStartDate.getFullYear()) +1);
			sJapaneseEra += " " + eraYear.toString();

			return sJapaneseEra;
		}
	}
	//this date did no match any known values, so return the current year
	sJapaneseEra = dTestDate.getFullYear();
	return sJapaneseEra;
}

//function that will return the year from a given era
function getYearfromEra (sEra, iEraYear)
{
	var iYear;

	for (i=0; i < japaneseEras.length; i++)
	{
		if (sEra == japaneseEras[i].m_sName)
		{
			iEraYear = japaneseEras[i].m_dStartDate.getFullYear() + iEraYear - 1;
			return iEraYear;
		}
	}
	return false;
}

//this will test for a valid japanese era,
//strip it out and then pass the value to the standard
//date parser to finish the job
function dParseEra(sTestDate, sInputOrder)
{
	//split the string into an array based on non alphanumeric delimeters
	var rDelimiters = /[ ,\.-\/\\#\:]/g;
	var rNoIntegers = /[^0-9]/;

	var sEra = null;
	var iEraYear = null;
	var bFoundEra = false;
	var bFoundEraYear = false;
	var iEraPosition = null;
	var dEraDate = false;

	var arDateTokens = sTestDate.split(rDelimiters);

	//find the token with the era
	for (i=0; i < arDateTokens.length; i++)
	{
		//there are characters in this token?
		if (arDateTokens[i].search(rNoIntegers) != -1)
		{
			//is it an era?
			for (j=0; j < japaneseEras.length; j++)
			{
				var sTestEra =  arDateTokens[i];

				if (sTestEra.length > japaneseEras[j].m_sName.length)
				{
					sTestEra = sTestEra.substring(0, japaneseEras[j].m_sName.length);
				}
				var myEra = new RegExp("^" + sTestEra, "i"); //ignore case
				//is there a match?
				if (japaneseEras[j].m_sName.match(myEra))
				{
					bFoundEra=true;
					iEraPosition = i;
					sEra = japaneseEras[j].m_sName;

					//is there a number to the right of the era?
					if (iEraPosition + 1 < arDateTokens.length )
					{
						//is it a number?
						//var rNoIntegers = /[^0-9]/;
						var y = arDateTokens[iEraPosition + 1].search(rNoIntegers);
						if (y == -1)
						{
							bFoundEraYear= true;
							iEraYearPosition = i+1;
							iEraYear =  parseInt(arDateTokens[iEraPosition + 1],10);
						}
					}
				}
			}
		}
	}

	if ((bFoundEra === true) && (bFoundEraYear === true))
	{
		var sProcessedDate = "";
		var sConvertedEraYear = getYearfromEra(sEra, iEraYear);
		//concatenate back into a string
		for (m=0; m < arDateTokens.length; m++)
		{
			if (m == iEraPosition)
			{
				//add the converted era to the string
				sProcessedDate += " " + sConvertedEraYear;
			}
			else if (m==iEraYearPosition)
			{
				//do nothing
			}
			else
			{
				//add to the end of the string
				sProcessedDate += " " + arDateTokens[m];
			}
		}

		dEraDate = dParseDate(sProcessedDate, sInputOrder);
	}
	//couldn't find a valid era, it might still be a valid date
	else
	{
		dEraDate = dParseDate(sTestDate, sInputOrder);
	}

	return dEraDate;
}

//test to a year to see if there is a corresponding
//Imperial era
function iTestEra(sTestYear)
{
	var rDelimiters = /[ ,\.-\/\\#\:]/g;
	var arDateTokens = sTestYear.split(rDelimiters);
	var sTestEra = arDateTokens[0];
	var bFoundEra = false;
	var sFoundEra ="";
	var iFoundEraYear = null;
	if (arDateTokens.length == 2)
	{
		//is it an era?
		for (j=0; j < japaneseEras.length; j++)
		{
			if (sTestEra.length > japaneseEras[j].m_sName.length)
			{
				sTestEra = sTestEra.substring(0, japaneseEras[j].m_sName.length);
			}
			var myEra = new RegExp("^" + sTestEra, "i"); //ignore case
			//is there a match?
			if (japaneseEras[j].m_sName.match(myEra))
			{
				bFoundEra = true;
				sFoundEra =  japaneseEras[j].m_sName;
				iFoundEraYear = parseInt(arDateTokens[1],10);
			}
		}

		if (bFoundEra === true)
		{
			return getYearfromEra (sFoundEra, iFoundEraYear);
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}

//this function will convert 2 digit years to a 4 digit
//year using the following convention:
//	00-49 converted to 20**
//  50-99 converted to 19**
function sShortToFullYearConversion(sShortYear)
{
	if (sShortYear.length == 2)
	{
		var iTestYear = parseInt(sShortYear,10);
		if (iTestYear >= MIN_YEAR && iTestYear <= MAX_YEAR)
		{
			iTestYear = iTestYear + 2000;
		}
		else
		{
			iTestYear = iTestYear + 1900;
		}
		var sConvertedYear = iTestYear.toString();
		return sConvertedYear;
	}
	else
	{
		//not a valid 2 digit year
		return false;
	}
}

// Default Date Arrays
//these values are used if locale information is not available.
g_arMonths = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
g_arMonthsAbbr = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
g_arDays = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
g_arDaysAbbr = new Array("Su", "Mo", "Tu", "We", "Th", "Fr", "Sa");
g_amString = "AM";
g_pmString = "PM";
g_startDayOfWeek = 1;  // 1 = Sunday, 2 = Monday, etc...
g_mediumFormat = "MMM d, yyyy h:mm:ss a";
g_shortFormat = "M/d/yy h:mm a";
g_dateOrder = "MDY";
g_yearFormatMedium = "yyyy";
g_monthFormatMedium = "MMM";
g_dayFormatMedium = "d";
g_hourFormatMedium = "h";
g_minuteFormatMedium = "mm";
g_secondFormatMedium = "ss";
g_yearFormatShort = "yy";
g_monthFormatShort = "M";
g_dayFormatShort = "d";
g_hourFormatShort = "h";
g_minuteFormatShort = "mm";
g_secondFormatShort = "";
g_dateSeparatorMedium = " ";
g_dateSeparatorShort = "/";
g_timeSeparator = ":";

var japaneseEras = new Array();
japaneseEras[0] = new japaneseEra('Meiji', '1868', '8', '8', '1912', '7', '29');
japaneseEras[1] = new japaneseEra('Taisho', '1912', '7', '30', '1926', '12', '24');
japaneseEras[2] = new japaneseEra('Showa', '1926', '12', '25', '1989', '1', '7');
japaneseEras[3] = new japaneseEra('Heisei', '1989', '1', '8', '2087', '12', '31');

//2 digit year conversions
MIN_YEAR = 0;
MAX_YEAR = 49;