
	function makeArray()    {
		this[0] = makeArray.arguments.length;
		for (i = 0; i<makeArray.arguments.length; i++)
			this[i+1] = makeArray.arguments[i];
	}

	var daysofmonth   = new makeArray( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
	var daysofmonthLY = new makeArray( 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

	function LeapYear(year) {
		if ((year/4)   != Math.floor(year/4))   return false;
		if ((year/100) != Math.floor(year/100)) return true;
		if ((year/400) != Math.floor(year/400)) return false;
		return true;
	}

	function NthDay(nth,weekday,month,year) {
		if (nth > 0) return (nth-1)*7 + 1 + (7 + weekday -
	DayOfWeek((nth-1)*7 + 1,month,year))%7;
		if (LeapYear(year)) var days = daysofmonthLY[month];
		else                var days = daysofmonth[month];
		return days - (DayOfWeek(days,month,year) - weekday + 7)%7;
	}

	function DayOfWeek(day,month,year) {
		var a = Math.floor((14 - month)/12);
		var y = year - a;
		var m = month + 12*a - 2;
		var d = (day + y + Math.floor(y/4) - Math.floor(y/100) +
	Math.floor(y/400) + Math.floor((31*m)/12)) % 7;
		return d+1;
	}

	function y2k(number)    { return (number < 1000) ? number + 1900 : number; }

	var today = new Date();
	var year = y2k(today.getYear());

	var DSTstart = new Date(year,4-1,NthDay(1,1,4,year),2,0,0);
	var DSTend   = new Date(year,10-1,NthDay(-1,1,10,year),2,0,0);

	function getMS(date) {
		return Date.UTC(y2k(date.getYear()),date.getMonth(),date.getDate(),date.getHours(),date.getMinutes(),date.getSeconds())
	}


	function isDST(aDate) {
		var aDateMS = getMS(aDate);
		var DSTstartMS = getMS(DSTstart);
		var DSTendMS = getMS(DSTend);
		
		if (aDateMS > DSTstartMS && aDateMS < DSTendMS)
			return true;
		else
			return false;
	}
	var ArrSTZ = new Array (
			new DatePair("GMT", 0),
			new DatePair("CET", 1),
			new DatePair("EET", 2),
			new DatePair("MSK", 3),
			new DatePair("NST", -3.5),
			new DatePair("AST", -4),
			new DatePair("EST", -5),
			new DatePair("CST", -6),
			new DatePair("MST", -7),
			new DatePair("PST", -8),
			new DatePair("HST", -10),
			new DatePair("AKST", -9),
			new DatePair("AEST", 10),
			new DatePair("AWST", 8),
			new DatePair("ACST", 9.5));

	var ArrDSTZ = new Array (
			new DatePair("BST", 1),
			new DatePair("CEST", 2),
			new DatePair("EEST", 3),
			new DatePair("MSD", 4),
			new DatePair("NDT", -2.5),
			new DatePair("ADT", -3),
			new DatePair("EDT", -4),
			new DatePair("CDT", -5),
			new DatePair("MDT", -6),
			new DatePair("PDT", -7),
			new DatePair("AKDT", -8),
			new DatePair("AEDT", 11),
			new DatePair("ACDT", 10.5));

		


	function DatePair(sName, nOffset)
	{
		this.m_nOffSet = nOffset * 60;
		this.m_sName = sName;
		this.match = matchOffsetInMin;
	}

	function matchOffsetInMin(nMin)
	{
		return (this.m_nOffSet) == nMin;
	}


	function getTZName(d)
	{
		var ArrToTakeFrom = null;
		var nOffsetInMin = 0;
		if (isDST(d))
		{
			ArrToTakeFrom = ArrDSTZ;
			nOffsetInMin  = (d.getTimezoneOffset()) * -1;
		}
		else
		{	
			ArrToTakeFrom = ArrSTZ;
			nOffsetInMin  = d.getTimezoneOffset() * -1;
		}
		var i = 0;
		while ((i < ArrToTakeFrom.length) && (!ArrToTakeFrom[i].match(nOffsetInMin)))
			++i
		if (i == ArrToTakeFrom.length)
			return "GMT " + (nOffsetInMin / 60);
		else
			return ArrToTakeFrom[i].m_sName;		
	}
	function getTwoDigForDate(nNum)
	{
		if (parseInt(nNum) < 10)
			return "0" + nNum;
		else
			return nNum;
	}

	function getTimeZoneOffsetInMin(sDate)
	{
		sDate = removeTimeZoneFromString(sDate);
		var nOffsetInMin = 0;
		d = new Date(sDate);

		nOffsetInMin  = d.getTimezoneOffset() * -1;

/* // Remarked by Eran, 2/8/2004 - The offset already compensate this difference			
		if (isDST(d)){
			nOffsetInMin  = (d.getTimezoneOffset() - 60) * -1;
		}
		else{	
			nOffsetInMin  = d.getTimezoneOffset() * -1;
		}
		*/
		return nOffsetInMin;
	}

	/***********************************************************/
	/*************		Format Functions		****************/
	function getTwoDigForDate(nNum)
	{
		if (parseInt(nNum) < 10)
			return "0" + nNum;
		else
			return nNum;
	}

	function formatDate(DateObj)
	{
		return  (DateObj.getMonth() + 1) + "/" + DateObj.getDate() + "/" + DateObj.getYear() + " " + getTwoDigForDate(DateObj.getHours()) + ":" + getTwoDigForDate(DateObj.getMinutes());
	}

	function convertUTCToLocal(sDate)
	{
		sDate = removeTimeZoneFromString(sDate);
		dOriginal = new Date(sDate);
		nOrigMillis = dOriginal.valueOf();
		nMinuteOffset = getTimeZoneOffsetInMin(sDate);
		nMillisecOffset = nMinuteOffset * 60000; //convert minutes to milliseconds
		nOrigMillis += nMillisecOffset;
		dLocalDate = new Date(nOrigMillis);
		return formatDate(dLocalDate);
	}

	function convertLocalToUTC(sDate)
	{
		sDate = removeTimeZoneFromString(sDate);
		dOriginal = new Date(sDate);
		nOrigMillis = dOriginal.valueOf();
		nMinuteOffset = getTimeZoneOffsetInMin(sDate);
		mMillisecOffset = nMinuteOffset * 60000; //convert minutes to milliseconds
		nOrigMillis -= mMillisecOffset;
		dLocalDate = new Date(nOrigMillis);
		return formatDate(dLocalDate);
	}

	function getTimeZoneFromString(sDate)
	{
		return getTZName(new Date(sDate));
	}

	function getTimeZoneFromDate(d)
	{
		return getTZName(d);
	}

	function removeTimeZoneFromString(sDate)
	{
		var i = sDate.indexOf(":");
		if (i == -1)
			return sDate;
		sDate = sDate.substr(0,i+3);
		
		return sDate;
	}

	/*******************************************************/
	/***********		Test Funtions		****************/

	function testConvertToLocal()
	{
		var sUTC = txtIn.value;
		var sLocal = convertUTCToLocal(sUTC);
		txtOut.value = sLocal;
	}

	function testConvertToUTC()
	{
		var sLocal = txtIn.value;
		var sUTC = convertLocalToUTC(sLocal);
		txtOut.value = sUTC;
	}

	function testGetTimeZone()
	{
		alert(getTimeZoneFromString(txtOut.value));
	}
