﻿/*Nagesh Chopra*/
/****LocalToUTCTime*** :: 
Function to convert Local time of a specified timezone to equivalent UTC time.
***Parameters*** ::
poLocalDateTime -> Date object for the Local datetime value.
pnTimeZoneID -> Numeric TimeZoneID value, representing the source timezone of local time.
***Returns***
Date object, containing UTC Time
*/
function LocalToUTCTime(poLocalDateTime, pnTimeZoneID)
{
    var loUTCDateTime = "";
    var lnTZOffsetInMinutes = 0;    

    try
    {
        /*if poLocalDateTime is not a date object, try to create a date object for the given value*/
        if ( (poLocalDateTime == null) || (poLocalDateTime.constructor != Date) )
        {   poLocalDateTime = new Date(poLocalDateTime);    }    

        /*Raise an exception, if the parameter Local datetime value if still an invalid date object*/
        if (isNaN(poLocalDateTime))
        {
            throw new Error("Exception raised from 'LocalToUTCTime':: "
                            + "DateTime parameter is not a valid date/date object");
        }
        
        /*Create a $$TimeZone object for specified TimeZoneID*/
        var loTimeZone = new $$TimeZone(pnTimeZoneID);
        /*if $$TimeZone object creation succeeded; i.e. TimeZoneID was a valid value.*/
        if (loTimeZone.constructor == $$TimeZone)
        {
            var lnYear = poLocalDateTime.getFullYear(); /*year part of the date*/
            var loDSTStartDateTime= loTimeZone.DSTStartDate(lnYear); /*start date for DST period*/
            var loDSTEndDateTime = loTimeZone.DSTEndDate(lnYear); /*end date for DST period*/

            /*If the DateTime value falls withing DST period, adjust daylight bias also.*/ 
            if ( (poLocalDateTime >= loDSTStartDateTime) && (poLocalDateTime < loDSTEndDateTime) )
            {   lnTZOffsetInMinutes = loTimeZone.nBias + loTimeZone.nDaylightBias;     }
            else
            {   lnTZOffsetInMinutes = loTimeZone.nBias;    }
        }

        // convert local time to msec
        // convert time zone offset to msec and subtract
        // get UTC time in msec
        var loUTCDateTime = new Date(poLocalDateTime.getTime() - (lnTZOffsetInMinutes * 60000));
        /*1000 milliseconds = 1 second, and 1 minute = 60 seconds. Therefore, converting minutes to milliseconds involves multiplying by 60 * 1000 = 60000.*/
    }
    catch(loError)
    {
        var lsErrorMessage = "Error:: Unexpected failure while converting "
                                + "Local Time to UTC Time";
        if (typeof($Exception) == "function")
        {   $Exception(loError, lsErrorMessage);    }
        else 
        {   alert(lsErrorMessage);  }        
    }
    finally
    {
        return loUTCDateTime;
    }
}

/*Nagesh Chopra*/
/****UTCToLocalTime*** :: 
Function to convert UTC time to equivalent Local time of a specified timezone.
***Parameters*** ::
poUTCDateTime -> Date object for the UTC datetime value.
pnTimeZoneID -> Numeric TimeZoneID value, representing the target timezone for local time.
***Returns***
Date object, containing Local Time
*/
function UTCToLocalTime(poUTCDateTime, pnTimeZoneID)
{
    var loLocalDateTime = "";
    var lnTZOffsetInMinutes = 0;
    
    try
    {
        /*if poUTCDateTime is not a date object, try to create a date object for the given value*/
        if ( (poUTCDateTime == null) || (poUTCDateTime.constructor != Date) )
        {   poUTCDateTime = new Date(poUTCDateTime);   }    

        /*Raise an exception, if the parameter UTC datetime value if still an invalid date object*/
        if (isNaN(poUTCDateTime))
        {
            throw new Error("Exception raised from 'UTCToLocalTime':: "
                            + "DateTime parameter is not a valid date/date object");
        }

        /*Create a $$TimeZone object for specified TimeZoneID*/
        var loTimeZone = new $$TimeZone(pnTimeZoneID);
        /*if $$TimeZone object creation succeeded; i.e. TimeZoneID was a valid value.*/
        if (loTimeZone.constructor == $$TimeZone)
        {
            var lnYear = poUTCDateTime.getFullYear(); /*year part of the date*/
            var loDSTStartDateTime= loTimeZone.DSTStartDate(lnYear); /*start date for DST period*/
            var loDSTEndDateTime = loTimeZone.DSTEndDate(lnYear); /*end date for DST period*/

            lnTZOffsetInMinutes = loTimeZone.nBias;
            // convert utc time to msec
            // convert time zone offset to msec and add
            // get local time in msec
            loLocalDateTime = new Date(poUTCDateTime.getTime() + (lnTZOffsetInMinutes * 60000));
            /*1000 milliseconds = 1 second, and 1 minute = 60 seconds. Therefore, converting minutes to milliseconds involves multiplying by 60 * 1000 = 60000.*/
            
            /*If the DateTime value falls withing DST period, adjust daylight bias also.*/ 
            if ( (loLocalDateTime >= loDSTStartDateTime) && (loLocalDateTime < loDSTEndDateTime) )
            {
                lnTZOffsetInMinutes = loTimeZone.nDaylightBias;
                // convert utc time to msec
                // convert time zone offset to msec and add
                // get local time in msec
                loLocalDateTime = new Date(loLocalDateTime.getTime() + (lnTZOffsetInMinutes * 60000));
                /*1000 milliseconds = 1 second, and 1 minute = 60 seconds. Therefore, converting minutes to milliseconds involves multiplying by 60 * 1000 = 60000.*/            
            }
        }
    }
    catch(loError)
    {
        var lsErrorMessage = "Error:: Unexpected failure while converting "
                                + "UTC Time to Local Time";
        if (typeof($Exception) == "function")
        {   $Exception(loError, lsErrorMessage);    }
        else 
        {   alert(lsErrorMessage);  }        
    }
    finally
    {
        return loLocalDateTime;
    }    
}


/*Nagesh Chopra*/
/*****CalcDateForWeekdayOfMonth***** ::  Function to calculate a date for the given 
week day of given month. Assembles the date parts to return a valid date.
***Parameters*** ::
pnInYear - > Year 
pnInMonth - > Month of the Year
pnInWeek - > Week of the Month
pnInWeekday - > Weekday of the Week/Month
pnInHour - > Hour of the day
***Returns*** ::
Date() object with a DateTime value.
*/
function CalcDateForWeekdayOfMonth(pnInYear, pnInMonth, pnInWeek, pnInWeekday, pnInHour)
{
   loDate = new Date(pnInMonth + "/01/" + pnInYear);
   lnWeekdayDiff = pnInWeekday - loDate.getDay();
   
   if (pnInWeek == 5)
   {
      lnTmpYear = pnInYear;
      lnTmpMonth = pnInMonth + 1;

      if (lnTmpMonth > 12)
      {
         lnTmpMonth = 1;
         lnTmpYear = pnInYear + 1;
      }
      loTmpDate = new Date(lnTmpMonth + "/01/" + lnTmpYear)
      loDate2 = new Date(loTmpDate.setDate(loTmpDate.getDate()-1));

      lnWeekdayDiff = pnInWeekday - loDate2.getDay();

      if (lnWeekdayDiff < 0)
      {
         lnOutDay = (loDate2.getDate() + lnWeekdayDiff);
      }
      else if (lnWeekdayDiff > 0)
      {
           lnOutDay = (loDate2.getDate()-(7-lnWeekdayDiff));
      }
      else if (lnWeekdayDiff == 0)
      {
         lnOutDay = loDate2.getDate();
      }
   }
   else
   {
      if (lnWeekdayDiff < 0)
      {     lnOutDay = ((pnInWeek) * 7) + (7 + lnWeekdayDiff) + 1;      }
      else if (lnWeekdayDiff > 0)
      {     lnOutDay = ((pnInWeek) * 7) + lnWeekdayDiff + 1;            }
      else if (lnWeekdayDiff == 0)
      {     lnOutDay = ((pnInWeek) * 7) + 1;                          }
   }

   loOutDate = new Date(pnInMonth + "/" + lnOutDay + "/" + pnInYear + " " + pnInHour + ":00");

   return loOutDate;

}




// Formats the given time to the requirements of the form field.
function GetFormattedTime( timeStr ){
	
	var retTimeStr = '';
	
	if (timeStr!='') {
		// Checks if time is in HH:MM:SS AM/PM format.
		// Copied for timevalidation function on formvalidation.inc.
		var timePat = /^(\d{1,2})(\s?(:))?(\d{0,2})(\s?(AM|am|Am|aM|PM|pm|Pm|pM))?$/;
		var matchArray = timeStr.match(timePat);
		
		// If no match, then return a blank string.
		if (matchArray == null) {
			retTimeStr = '';
		
		// Otherwise, format the string.
		} else {
		
			var blnTimeIsValid = new Boolean(true);

			hour = matchArray[1];
			dble = matchArray[3];
			minute = matchArray[4];
			ampm = matchArray[6];
			
			if (ampm==""){ ampm = null; }
			if (dble==""){ dble = null; }
			if (minute==""){ minute = null; }

			if (hour < 0  || hour > 12) { blnTimeIsValid = false; }
			if (ampm == null) { blnTimeIsValid = false;	}
			if (minute < 0 || minute > 59) { blnTimeIsValid = false; }
			if (dble != null  &&  minute == null) { blnTimeIsValid = false; }
			
			// If time is valid, then format it here.
			if (blnTimeIsValid){
				// Make sure hour is str of two digits.
				if (hour.length == 1){ hour = '0' + hour; }
				
				// Make sure minute is str of two digits.
				if (minute == null){ 
					minute = '00';
				} else if (minute.length == 1){ 
					minute = '0' + minute; 
				}
				
				retTimeStr = hour + ':' + minute + ' ' + ampm;
			}
		}
	}
	
	return retTimeStr;
}


// Creates the new end time, one hour after the start time.
function GetNewEndTime( starttime_dtfmt, starttime_fmt )
{

    var start_minutes = starttime_fmt.substring(3,5);
	//var start_ampmtag = starttime_fmt.substring(6,8);				
	
	var new_start_hours = starttime_dtfmt.getHours();
	var orig_start_hours = new_start_hours;


	// Add an hour to start time to get ending time.
	// Must NOT add more than 24 hours to the start time.
	new_start_hours++;

	// Check if time moved to next day.
	if (new_start_hours > 23){
		// If moved to next day, use original time.
		new_start_hours = orig_start_hours;
	}
	
	// Change from 24 hour clock to 12 hour w/ am/pm.
	// Don't have to worry about 0 o'clock because 
	//	we are adding an hour in the previous step.
	var ampmtag = 'am';
	if (new_start_hours > 11){ ampmtag = 'pm'; }
	if (new_start_hours > 12){ new_start_hours -= 12; }
	if (new_start_hours == 0){ new_start_hours = 12; }

	// Format hours new ending time.
	if (new_start_hours < 10){
		new_start_hours = '0' + new_start_hours;
	}
	var newendtime = new_start_hours + ':' + start_minutes + ' ' + ampmtag;

	return newendtime;
}


// Returns a javascript Date object.
// Assumes time given in appropriate format.
function GetDateFromTime( time ){
	// Change hours to 24 hour clock format.
	var time_dtfmt = new Date( 'January 1, 2000 ' + time );

	return time_dtfmt;
}

function FlipAmPmTag( tag ){
	if ( /[aA][mM]/.test( tag ) ){
		return 'pm';
	} else {
		return 'am';
	}
}


/*Nagesh Chopra*/
/*Add the "format" method to Date() object's prototype. 
Returns a formatted DateTime string matching the "mask" format.
***Parameters*** :: 
mask -> format specification/skeleton/mask for the desired DateTime string output.
***Returns*** ::
Formatted Date/Time or DateTime value as a String
*/
Date.prototype.format = function(mask) {
	var d = this; // Needed for the replace() closure
	
	// If preferred, zeroize() can be moved out of the format() method for performance and reuse purposes
	var zeroize = function (value, length) {
		if (!length) length = 2;
		value = String(value);
		for (var i = 0, zeros = ''; i < (length - value.length); i++) {
			zeros += '0';
		}
		return zeros + value;
	};
	
	return mask.replace(/"[^"]*"|'[^']*'|\b(?:d{1,4}|m{1,4}|yy(?:yy)?|([hHMs])\1?|TT|tt|[lL])\b/g, function($0) {
		switch($0) {
			case 'd':	return d.getDate();
			case 'dd':	return zeroize(d.getDate());
			case 'ddd':	return ['Sun','Mon','Tue','Wed','Thr','Fri','Sat'][d.getDay()];
			case 'dddd':	return ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'][d.getDay()];
			case 'm':	return d.getMonth() + 1;
			case 'mm':	return zeroize(d.getMonth() + 1);
			case 'mmm':	return ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'][d.getMonth()];
			case 'mmmm':	return ['January','February','March','April','May','June','July','August','September','October','November','December'][d.getMonth()];
			case 'yy':	return String(d.getFullYear()).substr(2);
			case 'yyyy':	return d.getFullYear();
			case 'h':	return d.getHours() % 12 || 12;
			case 'hh':	return zeroize(d.getHours() % 12 || 12);
			case 'H':	return d.getHours();
			case 'HH':	return zeroize(d.getHours());
			case 'M':	return d.getMinutes();
			case 'MM':	return zeroize(d.getMinutes());
			case 's':	return d.getSeconds();
			case 'ss':	return zeroize(d.getSeconds());
			case 'l':	return zeroize(d.getMilliseconds(), 3);
			case 'L':	var m = d.getMilliseconds();
					if (m > 99) m = Math.round(m / 10);
					return zeroize(m);
			case 'tt':	return d.getHours() < 12 ? 'am' : 'pm';
			case 'TT':	return d.getHours() < 12 ? 'AM' : 'PM';
			// Return quoted strings with the surrounding quotes removed
			default:	return $0.substr(1, $0.length - 2);
		}
	});
};

/*Nagesh Chopra*/
/*Add the method "CalcDateForWeekdayOfMonth" to Date() object's prototype.*/
Date.prototype.CalcDateForWeekdayOfMonth = CalcDateForWeekdayOfMonth;

/*Nagesh Chopra*/
/*****$$TimeZone****** :: Function based on "Prototype-Oriented programming".
It creates a TimeZone object, by looking up for the "pnTimeZoneID" index in the global
array of timezones "gaTimeZones".
**Properties** : -> a number of properties representing a timezone.
**Methods** : - > DSTStartDate(), DSTEndDate()
***Parameters*** ::
pnTimeZoneID -> Numeric value for TimeZoneID
***Returns*** ::
Object of type "$$TimeZone"
*/
/*"$$" prefix used to indicate that this function is intended to be used for  
creating and using class-less, prototype based objects.*/
function $$TimeZone(pnTimeZoneID)
{
    try
    {
        /*Initialize global array of timezones, if it's not already initialized.*/
        if (typeof(gaTimeZones) == "undefined" || gaTimeZones.constructor != Array) 
        { InitTimeZonesArray(); }        

        /*Raise an exception, If the parameter TimeZone ID isn't a valid numeric value
        or if it causes a FencePost error (value outside boundary of the array)*/
        if (isNaN(pnTimeZoneID) || pnTimeZoneID <= 0 || pnTimeZoneID >= gaTimeZones.length)
        {
            throw new Error("Invalid TimeZoneID provided.");            
        }

        this.nTimeZoneID = gaTimeZones[pnTimeZoneID][_TZ_TimeZoneID]; /*Unique ID for TimeZone*/
        this.sDisplayName = gaTimeZones[pnTimeZoneID][_TZ_DisplayName]; /*Diff between UTC and the time zone, in minutes*/
        this.sStandardName = gaTimeZones[pnTimeZoneID][_TZ_StandardName]; /*Name of time zone while standard time is in effect*/
        this.sDaylightName = gaTimeZones[pnTimeZoneID][_TZ_DaylightName]; /*Name of time zone while daylight savings time is in effect*/
        this.nBias = gaTimeZones[pnTimeZoneID][_TZ_Bias]; /*Diff between UTC and the time zone, in minutes*/
        this.nDaylightBias = gaTimeZones[pnTimeZoneID][_TZ_DaylightBias]; /*Additional bias to apply when DST is in effect*/
        this.nStandardMonth = gaTimeZones[pnTimeZoneID][_TZ_StandardMonth]; /*Month in which change time zone switches from DST to standard*/
        this.nStandardWeek = gaTimeZones[pnTimeZoneID][_TZ_StandardWeek]; /*Week of month in which change occurs*/
        this.nStandardDayOfWeek = gaTimeZones[pnTimeZoneID][_TZ_StandardDayOfWeek]; /*Day of week on which change occurs*/
        this.nStandardHour = gaTimeZones[pnTimeZoneID][_TZ_StandardHour]; /*Hour of Day on which change occurs*/
        this.nDaylightMonth = gaTimeZones[pnTimeZoneID][_TZ_DaylightMonth]; /*Month in which time zone switches from DST to standard*/
        this.nDaylightWeek = gaTimeZones[pnTimeZoneID][_TZ_DaylightWeek]; /*Week of month in which change occurs*/
        this.nDaylightDayOfWeek = gaTimeZones[pnTimeZoneID][_TZ_DaylightDayOfWeek]; /*Day of week on which change occurs*/
        this.nDaylightHour = gaTimeZones[pnTimeZoneID][_TZ_DaylightHour]; /*Hour of Day on which change occurs*/
        this.sStandardAbbreviation= gaTimeZones[pnTimeZoneID][_TZ_StandardAbbreviation]; /*Abbreviation for Standard Name*/
        this.sDaylightAbbreviation = gaTimeZones[pnTimeZoneID][_TZ_DaylightAbbreviation]; /*Abbreviation for Daylight Name*/
        
        /*Method to calculate/return Start Date of daylight saving period for the timezone.
        Parameter :: "pnYear" - > Year for which to return the DST start date.*/
        this.DSTStartDate = function(pnYear) 
            {
                /*calls a custom method added to Date() prototype, included in this file*/
                return new Date().CalcDateForWeekdayOfMonth(pnYear, this.nDaylightMonth,
                        this.nDaylightWeek, this.nDaylightDayOfWeek, this.nDaylightHour);
            };
            
        /*Method to calculate/return End Date of daylight saving period for the timezone.
        Parameter :: "pnYear" - > Year for which to return the DST end date.*/
        this.DSTEndDate = function(pnYear) 
            {
                /*calls a custom method added to Date() prototype, included in this file*/
                return new Date().CalcDateForWeekdayOfMonth(pnYear, this.nStandardMonth,
                        this.nStandardWeek, this.nStandardDayOfWeek, this.nStandardHour);
            };        
    }
    catch(loError)
    {
        /*catch the exception; raise an alert*/
        var lsErrorMessage = "Error:: Unexpected failure while creating a TimeZone object.";
        if (typeof($Exception) == "function")
        {   $Exception(loError, lsErrorMessage);    }
        else 
        {   alert(lsErrorMessage);  }        
        
        /*set the constructor for this object as "null"; useful for detecting a failure 
        in object creation at the usage site.*/
        this.constructor = null;
    }
    finally {}
}

/*Nagesh Chopra*/
/******InitTimeZonesArray****** :: Function to initialize/declare 
a global array of TimeZones, and global ordinals(index variables) for this array
***Parameters*** :: NOTHING
***Returns*** :: NOTHING
*/
function InitTimeZonesArray()
{

    _TZ_TimeZoneID = 0
    _TZ_DisplayName = 1
    _TZ_StandardName = 2
    _TZ_DaylightName = 3
    _TZ_Bias = 4
    _TZ_DaylightBias = 5
    _TZ_StandardMonth = 6
    _TZ_StandardWeek = 7
    _TZ_StandardDayOfWeek = 8
    _TZ_StandardHour = 9
    _TZ_DaylightMonth = 10
    _TZ_DaylightWeek = 11
    _TZ_DaylightDayOfWeek = 12
    _TZ_DaylightHour = 13
    _TZ_StandardAbbreviation = 14
    _TZ_DaylightAbbreviation = 15

    gaTimeZones = new Array();

    gaTimeZones[0] = [0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];

    gaTimeZones[1] = [1, "(GMT+04:00) Abu Dhabi, Muscat", "Arabian Standard Time", "Arabian Daylight Time", 240, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[2] = [2, "(GMT+03:00) Baghdad", "Arabic Standard Time", "Arabic Daylight Time", 180, 60, 10, 1, 0, 4, 4, 1, 0, 3, "", ""];
    gaTimeZones[3] = [3, "(GMT-04:00) Atlantic Time (Can", "Atlantic Standard Time", "Atlantic Daylight Time", -240, 60, 11, 0, 0, 2, 3, 1, 0, 2, "AST", "ADT"];
    gaTimeZones[4] = [4, "(GMT+09:30) Darwin", "AUS Central Standard Time", "AUS Central Daylight Time", 570, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[5] = [5, "(GMT+10:00) Canberra, Melbourn", "AUS Eastern Standard Time", "AUS Eastern Daylight Time", 600, 60, 3, 5, 0, 3, 10, 5, 0, 2, "", ""];
    gaTimeZones[6] = [6, "(GMT-01:00) Azores", "Azores Standard Time", "Azores Daylight Time", -60, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[7] = [7, "(GMT-06:00) Saskatchewan", "Canada Central Standard Time", "Canada Central Daylight Time", -360, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[8] = [8, "(GMT-01:00) Cape Verde Is.", "Cape Verde Standard Time", "Cape Verde Daylight Time", -60, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[9] = [9, "(GMT+04:00) Baku, Tbilisi, Yer", "Caucasus Standard Time", "Caucasus Daylight Time", 240, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[10] = [10, "(GMT+09:30) Adelaide", "Cen. Australia Standard Time", "Cen. Australia Daylight Time", 570, 60, 3, 5, 0, 3, 10, 5, 0, 2, "", ""];
    gaTimeZones[11] = [11, "(GMT-06:00) Central America", "Central America Standard Time", "Central America Daylight Time", -360, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[12] = [12, "(GMT+06:00) Astana, Dhaka", "Central Asia Standard Time", "Central Asia Daylight Time", 360, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[13] = [13, "(GMT+01:00) Belgrade, Bratisla", "Central Europe Standard Time", "Central Europe Daylight Time", 60, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[14] = [14, "(GMT+01:00) Sarajevo, Skopje, ", "Central European Standard Time", "Central European Daylight Time", 60, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[15] = [15, "(GMT+11:00) Magadan, Solomon I", "Central Pacific Standard Time", "Central Pacific Daylight Time", 660, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[16] = [16, "(GMT-06:00) Central Time (US &", "Central Standard Time", "Central Daylight Time", -360, 60, 11, 0, 0, 2, 3, 1, 0, 2, "CST", "CDT"];
    gaTimeZones[17] = [17, "(GMT+08:00) Beijing, Chongqing", "China Standard Time", "China Daylight Time", 480, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[18] = [18, "(GMT-12:00) International Date", "Dateline Standard Time", "Dateline Daylight Time", -720, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[19] = [19, "(GMT+03:00) Nairobi", "E. Africa Standard Time", "E. Africa Daylight Time", 180, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[20] = [20, "(GMT+10:00) Brisbane", "E. Australia Standard Time", "E. Australia Daylight Time", 600, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[21] = [21, "(GMT+02:00) Bucharest", "E. Europe Standard Time", "E. Europe Daylight Time", 120, 60, 10, 5, 0, 1, 3, 5, 0, 0, "", ""];
    gaTimeZones[22] = [22, "(GMT-03:00) Brasilia", "E. South America Standard Time", "E. South America Daylight Time", -180, 60, 2, 2, 0, 2, 10, 3, 0, 2, "", ""];
    gaTimeZones[23] = [23, "(GMT-05:00) Eastern Time (US &", "Eastern Standard Time", "Eastern Daylight Time", -300, 60, 11, 0, 0, 2, 3, 1, 0, 2, "EST", "EDT"];
    gaTimeZones[24] = [24, "(GMT+02:00) Cairo", "Egypt Standard Time", "Egypt Daylight Time", 120, 60, 9, 5, 3, 2, 5, 1, 5, 2, "", ""];
    gaTimeZones[25] = [25, "(GMT+05:00) Ekaterinburg", "Ekaterinburg Standard Time", "Ekaterinburg Daylight Time", 300, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[26] = [26, "(GMT+12:00) Fiji, Kamchatka, M", "Fiji Standard Time", "Fiji Daylight Time", 720, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[27] = [27, "(GMT+02:00) Helsinki, Kyiv, Ri", "FLE Standard Time", "FLE Daylight Time", 120, 60, 10, 5, 0, 4, 3, 5, 0, 3, "", ""];
    gaTimeZones[28] = [28, "(GMT) Greenwich Mean Time : Du", "GMT Standard Time", "GMT Daylight Time", 0, 60, 10, 5, 0, 2, 3, 5, 0, 1, "", ""];
    gaTimeZones[29] = [29, "(GMT-03:00) Greenland", "Greenland Standard Time", "Greenland Daylight Time", -180, 60, 10, 5, 0, 2, 4, 1, 0, 2, "", ""];
    gaTimeZones[30] = [30, "(GMT) Casablanca, Monrovia", "Greenwich Standard Time", "Greenwich Daylight Time", 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[31] = [31, "(GMT+02:00) Athens, Istanbul, ", "GTB Standard Time", "GTB Daylight Time", 120, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[32] = [32, "(GMT-10:00) Hawaii", "Hawaiian Standard Time", "Hawaiian Daylight Time", -600, 60, 0, 0, 0, 0, 0, 0, 0, 0, "HST", "HADT"];
    gaTimeZones[33] = [33, "(GMT+05:30) Chennai, Kolkata, ", "India Standard Time", "India Daylight Time", 330, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[34] = [34, "(GMT+03:30) Tehran", "Iran Standard Time", "Iran Daylight Time", 210, 60, 9, 4, 2, 2, 3, 1, 0, 2, "", ""];
    gaTimeZones[35] = [35, "(GMT+02:00) Jerusalem", "Jerusalem Standard Time", "Jerusalem Daylight Time", 120, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[36] = [36, "(GMT+09:00) Seoul", "Korea Standard Time", "Korea Daylight Time", 540, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[37] = [37, "(GMT-06:00) Guadalajara, Mexic", "Mexico Standard Time", "Mexico Daylight Time", -360, 60, 9, 5, 0, 2, 5, 1, 0, 2, "", ""];
    gaTimeZones[38] = [38, "(GMT-07:00) Chihuahua, La Paz,", "Mexico Standard Time", "Mexico Daylight Time", -420, 60, 9, 5, 0, 2, 5, 1, 0, 2, "", ""];
    gaTimeZones[39] = [39, "(GMT-02:00) Mid-Atlantic", "Mid-Atlantic Standard Time", "Mid-Atlantic Daylight Time", -120, 60, 9, 5, 0, 2, 3, 5, 0, 2, "", ""];
    gaTimeZones[40] = [40, "(GMT-07:00) Mountain Time (US ", "Mountain Standard Time", "Mountain Daylight Time", -420, 60, 11, 0, 0, 2, 3, 1, 0, 2, "MST", "MDT"];
    gaTimeZones[41] = [41, "(GMT+06:30) Rangoon", "Myanmar Standard Time", "Myanmar Daylight Time", 390, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[42] = [42, "(GMT+06:00) Almaty, Novosibirs", "N. Central Asia Standard Time", "N. Central Asia Daylight Time", 360, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[43] = [43, "(GMT+05:45) Kathmandu", "Nepal Standard Time", "Nepal Daylight Time", 345, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[44] = [44, "(GMT+12:00) Auckland, Wellingt", "New Zealand Standard Time", "New Zealand Daylight Time", 720, 60, 3, 3, 0, 2, 10, 1, 0, 2, "", ""];
    gaTimeZones[45] = [45, "(GMT-03:30) Newfoundland", "Newfoundland Standard Time", "Newfoundland Daylight Time", -210, 60, 10, 5, 0, 2, 4, 1, 0, 2, "", ""];
    gaTimeZones[46] = [46, "(GMT+08:00) Irkutsk, Ulaan Bat", "North Asia East Standard Time", "North Asia East Daylight Time", 480, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[47] = [47, "(GMT+04:30) Kabul", "Afghanistan Standard Time", "Afghanistan Daylight Time", 270, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[48] = [48, "(GMT-09:00) Alaska", "Alaskan Standard Time", "Alaskan Daylight Time", -540, 60, 11, 0, 0, 2, 3, 1, 0, 2, "AKST", "AKDT"];
    gaTimeZones[49] = [49, "(GMT+03:00) Kuwait, Riyadh", "Arab Standard Time", "Arab Daylight Time", 180, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[50] = [50, "(GMT+07:00) Krasnoyarsk", "North Asia Standard Time", "North Asia Daylight Time", 420, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[51] = [51, "(GMT-04:00) Santiago", "Pacific SA Standard Time", "Pacific SA Daylight Time", -240, 60, 3, 2, 6, 0, 10, 2, 6, 0, "", ""];
    gaTimeZones[52] = [52, "(GMT-08:00) Pacific Time (US &", "Pacific Standard Time", "Pacific Daylight Time", -480, 60, 11, 0, 0, 2, 3, 1, 0, 2, "PST", "PDT"];
    gaTimeZones[53] = [53, "(GMT+01:00) Brussels, Copenhag", "Romance Standard Time", "Romance Daylight Time", 60, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[54] = [54, "(GMT+03:00) Moscow, St. Peters", "Russian Standard Time", "Russian Daylight Time", 180, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[55] = [55, "(GMT-03:00) Buenos Aires, Geor", "SA Eastern Standard Time", "SA Eastern Daylight Time", -180, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[56] = [56, "(GMT-05:00) Bogota, Lima, Quit", "SA Pacific Standard Time", "SA Pacific Daylight Time", -300, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[57] = [57, "(GMT-04:00) Caracas, La Paz", "SA Western Standard Time", "SA Western Daylight Time", -240, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[58] = [58, "(GMT-11:00) Midway Island, Sam", "Samoa Standard Time", "Samoa Daylight Time", -660, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[59] = [59, "(GMT+07:00) Bangkok, Hanoi, Ja", "SE Asia Standard Time", "SE Asia Daylight Time", 420, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[60] = [60, "(GMT+08:00) Kuala Lumpur, Sing", "Malay Peninsula Standard Time", "Malay Peninsula Daylight Time", 480, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[61] = [61, "(GMT+02:00) Harare, Pretoria", "South Africa Standard Time", "South Africa Daylight Time", 120, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[62] = [62, "(GMT+06:00) Sri Jayawardenepur", "Sri Lanka Standard Time", "Sri Lanka Daylight Time", 360, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[63] = [63, "(GMT+08:00) Taipei", "Taipei Standard Time", "Taipei Daylight Time", 480, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[64] = [64, "(GMT+10:00) Hobart", "Tasmania Standard Time", "Tasmania Daylight Time", 600, 60, 3, 5, 0, 3, 10, 1, 0, 2, "", ""];
    gaTimeZones[65] = [65, "(GMT+09:00) Osaka, Sapporo, To", "Tokyo Standard Time", "Tokyo Daylight Time", 540, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[66] = [66, "(GMT+13:00) Nuku'alofa", "Tonga Standard Time", "Tonga Daylight Time", 780, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[67] = [67, "(GMT-05:00) Indiana (East)", "US Eastern Standard Time", "US Eastern Daylight Time", -300, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[68] = [68, "(GMT-07:00) Arizona", "US Mountain Standard Time", "US Mountain Daylight Time", -420, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[69] = [69, "(GMT+10:00) Vladivostok", "Vladivostok Standard Time", "Vladivostok Daylight Time", 600, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[70] = [70, "(GMT+08:00) Perth", "W. Australia Standard Time", "W. Australia Daylight Time", 480, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[71] = [71, "(GMT+01:00) West Central Afric", "W. Central Africa Standard Tim", "W. Central Africa Daylight Tim", 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[72] = [72, "(GMT+01:00) Amsterdam, Berlin,", "W. Europe Standard Time", "W. Europe Daylight Time", 60, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];
    gaTimeZones[73] = [73, "(GMT+05:00) Islamabad, Karachi", "West Asia Standard Time", "West Asia Daylight Time", 300, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[74] = [74, "(GMT+10:00) Guam, Port Moresby", "West Pacific Standard Time", "West Pacific Daylight Time", 600, 60, 0, 0, 0, 0, 0, 0, 0, 0, "", ""];
    gaTimeZones[75] = [75, "(GMT+09:00) Yakutsk", "Yakutsk Standard Time", "Yakutsk Daylight Time", 540, 60, 10, 5, 0, 3, 3, 5, 0, 2, "", ""];

}

function JuliandDate(dateStr) {
    
    if (dateStr!="") {
		// Checks for the following valid date formats:
		// MM/DD/YY   MM/DD/YYYY   MM-DD-YY   MM-DD-YYYY
		// Also separates date into month, day, and year variables

		var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{2}|\d{4})$/;
		
		// Use the following line to require a 4-digit year
		// var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/;

		var matchArray = dateStr.match(datePat); // is the format ok?
		if (matchArray != null) {
			MM = parseInt(matchArray[1]) ; // parse date into variables
			DD = parseInt(matchArray[3]) ;
			YY =  parseInt(matchArray[4]) ;
            HR=0;
            MN=0;
            SC=0;
         
            with (Math) {  
                HR = HR + (MN / 60) + (SC/3600);
                
                GGG = 1;
                if (YY <= 1585) GGG = 0;
                JD = -1 * floor(7 * (floor((MM + 9) / 12) + YY) / 4);
                S = 1;
                if ((MM - 9)<0) S=-1;
                A = abs(MM - 9);
                
                J1 = floor(YY + S * floor(A / 7));
               
                J1 = -1 * floor((floor(J1 / 100) + 1) * 3 / 4);
                 
                JD = JD + floor(275 * MM / 9) + DD + (GGG * J1);
               
                JD = JD + 1721027 + 2 * GGG + 367 * YY - 0.5;
                
                JD = JD + (HR / 24);
            }
           
        return JD;
        }
        else return 0
    }
    else return 0
}
function computeDJ(jddate) {
  
    JD=eval(jddate)
  
  with (Math) {
    IJD = floor(JD);
    L = floor(IJD + 68569);
    N = floor(4 * L / 146097);
    L = L - floor((146097*N + 3)/4);
    I = floor(4000*(L + 1)/1461001);
    L = L - floor(1461 * I / 4) + 31;
    J = floor(80 * L / 2447);
    K = L - floor(2447 * J / 80);
    L = floor(J/11);
    J = J + 2 - 12*L;
    I = 100*(N - 49) + I + L;
  }
  if (JD != 0) {
    var datestr=J+'/'+K+'/'+I
    return  datestr 
  }
}