///   Start 
// Handles Date And Time Object and operations 
function DayLightSavingObj (offset,startTimeMili,endTimeMili)
{
   this.offset = offset;
   this.startTimeMili = startTimeMili;
   this.endTimeMili = endTimeMili;
}

DayLightSavingObj.prototype.copy = function (destDayLightSavingsObj)
{
    destDayLightSavingsObj.offset = this.offset;
    destDayLightSavingsObj.startTimeMili = this.startTimeMili;
    destDayLightSavingsObj.endTimeMili = this.endTimeMili;
}

// time zones ctor
function TimeZoneObj (id,shortName,country,region,cityList,timeZone,hasDayLightSavings)
{
    this.id = id;
    this.shortName = shortName;
    this.country = country;
    this.region = region;
    this.cityList = cityList;
    this.timeZone = timeZone;
    this.hasDayLightSavings = hasDayLightSavings;
    this.dayLightSavings = null;
}

TimeZoneObj.prototype.copy = function (destTimeZoneObj)
{
    destTimeZoneObj.id = this.id;
    destTimeZoneObj.shortName = this.shortName;
    destTimeZoneObj.country = this.country;
    destTimeZoneObj.region = this.region;
    destTimeZoneObj.cityList = this.cityList;
    destTimeZoneObj.timeZone = this.timeZone;
    destTimeZoneObj.hasDayLightSavings = this.hasDayLightSavings;
    if (this.dayLightSavings!=null)
    {
        var len = this.dayLightSavings.length;
        destTimeZoneObj.dayLightSavings = new Array();
        for (var i=0;i<len;i++)
        {
           destTimeZoneObj.dayLightSavings[i]=new DayLightSavingObj(-1,-1,-1);
           this.dayLightSavings[i].copy(destTimeZoneObj.dayLightSavings[i]);
        }
    }
}

TimeZoneObj.prototype.AddDayLightSavings = function (dayLightSavingObj)
{
    this.hasDayLightSavings = true;
    if (this.dayLightSavings==null)
    {
       this.dayLightSavings = new Array();
    }
    this.dayLightSavings[this.dayLightSavings.length]= dayLightSavingObj;
}
// generate a string for the server to understand
TimeZoneObj.prototype.toFullNameString = function (maxLen,isTxt)
{
    if (isTxt==null)
    {
        isTxt = false;
    }
    if (maxLen==null)
    {
        maxLen = 30;
    }
    var ret = '(GMT';
    if (this.timeZone >0)
    {
      ret += '+';
    }
    ret+= this.timeZone + ') ';
    var caption = this.country +'; ';
    caption += this.region;
    if (caption!='')
    {
       caption +='';
    }
    caption += this.cityList;
    
    if (!isTxt)
    {
        ret += '<span title="'+caption+'">';
    }
    ret += CutStringToSize(caption,maxLen);
    if (!isTxt)
    {
        ret += '</span>';
    }
    return ret;
}

TimeZoneObj.prototype.toFullNameStringGmtLast = function (maxLen,isTxt)
{
    if (isTxt==null)
    {
        isTxt = false;
    }
    if (maxLen==null)
    {
        maxLen = 30;
    }
    //alert(this.id);
    if(this.id == -1)
    {
        return '<span>Time zone region not selected</span>';
    }
    var ret = '&nbsp;(GMT';
    if (this.timeZone >0)
    {
      ret += '+';
    }
    ret+= this.timeZone + ') ';
    var caption = this.country +'; ';
    caption += this.region;
    if (caption!='')
    {
       caption +='';
    }
    caption += this.cityList;
    
    if (!isTxt)
    {
        ret += '<span title="'+caption+'">';
    }
    ret = CutStringToSize(caption,maxLen) + ret;
    if (!isTxt)
    {
        ret += '</span>';
    }
    return ret;
}

TimeZoneObj.prototype.toString = function ()
{
   return this.toFullNameString(10000);
}

// generate a string for the server to understand
TimeZoneObj.prototype.toFullNameWithoutCountryString = function ()
{
    var ret = '(GMT';
    if (this.timeZone >0)
    {
      ret += '+';
    }
    ret+= this.timeZone + ') ';
    var caption = this.region;
//    if (caption!='')
//    {
//       caption +=',';
//    }
//    caption += this.cityList;
    if (caption=='')
    {
       caption = this.country;
    }
    ret += ' ' + caption;
    return ret;
}

function sortByGMT(a,b)
{
    var x = a.timeZone;
    var y = b.timeZone;
    return ((x<y) ? -1 : ((x > y) ? 1 : 0));
}

TimeZoneObj.prototype.GetDlsChangeTime = function (startTime,endTime)
{
  var ret = null;
  if (this.hasDayLightSavings)
  {
     if (this.dayLightSavings!=null)
     {
       var len = this.dayLightSavings.length;
       for (var i=0;i<len;i++)
       {
           var dlsObj = this.dayLightSavings[i];
           if ((dlsObj.startTimeMili > startTime.innerMiliSecs) && (dlsObj.startTimeMili < endTime.innerMiliSecs))
           {
               ret = CreateNewDateFromMili(dlsObj.startTimeMili,this);
               break;
           }
           if ((dlsObj.endTimeMili > startTime.innerMiliSecs) && (dlsObj.endTimeMili < endTime.innerMiliSecs))
           {
               ret = CreateNewDateFromMili(dlsObj.endTimeMili,this);               
               break;
           }
       }
     }    
  }  
  
  return ret;
}

// date time ctor
function DateTimeObj (year,month,day,hours,minutes,seconds,tzObj,isTransform)
{
    this.m_yearForShow = -1;
    this.m_dateForShow = -1;
    this.m_dayForShow = -1;
    this.m_monthForShow = -1;
    this.m_fullYearForShow = -1;
   if (isTransform==null)
   {
      isTransform = false;
   }
   this.innerMiliSecs = Date.UTC(year,month,day,hours,minutes,seconds);
   if (tzObj!=null)
   {
     this.timeZoneObj = tzObj;
   }
   else
   {
     this.timeZoneObj = new TimeZoneObj (1,'UTC','(UTC/GMT)','','',0,false);
   }
   if (isTransform)
   {
        
       if (tzObj!=null)
       {
       
        var offset = this.GetTimeZoneOffset();
        //alert(offset);
        this.innerMiliSecs -= offset*HOUR_IN_MILISECONDS;
        var newOffset = this.GetTimeZoneOffset();
        if (newOffset!=offset)
        {
            offset = newOffset-offset;
            this.innerMiliSecs -= offset*HOUR_IN_MILISECONDS;
            
        }
       }
   }
}

DateTimeObj.prototype.fixForTimeZoneChange = function (oldTimezoneObj)
{
  var tzOffset = (this.timeZoneObj.timeZone-oldTimezoneObj.timeZone);
  var oldTime = CreateNewDateFromMili(this.innerMiliSecs,oldTimezoneObj);
  var dlsOffset = this.GetDLSOffset() - oldTime.GetDLSOffset();
  var nextTime = this.AddHours(tzOffset+dlsOffset);
  this.innerMiliSecs = nextTime.innerMiliSecs;
}
DateTimeObj.prototype.copy = function (destDateTimeObj,timezoneObj)
{
   destDateTimeObj.innerMiliSecs = this.innerMiliSecs;
   if (timezoneObj==null)
   {
      this.timeZoneObj.copy(destDateTimeObj.timeZoneObj);
   }
   else
   {
      destDateTimeObj.SetTimeZoneObj(timezoneObj);
   }
}

DateTimeObj.prototype.clone = function (timezoneObj)
{
   var ret = new DateTimeObj();
   this.copy (ret,timezoneObj);
    return ret;
}

var MINUTE_IN_MILISECONDS =1000*60; 
var HOUR_IN_MILISECONDS =MINUTE_IN_MILISECONDS*60; 
var DAY_IN_MILISECONDS = HOUR_IN_MILISECONDS*24;

function CreateNewDateFromMili(mili,timeZoneObj)
{
  var ret = new DateTimeObj(1970,1,1,0,0,0,timeZoneObj,false);
  ret.innerMiliSecs = mili;
  return ret;
}

function GetNowDateTime(timeZoneObj)
{
    dt = new Date();
    var ret = CreateNewDateFromMili(dt.getTime(),timeZoneObj);
    return ret ;
}

DateTimeObj.prototype.SetTimeZoneObj = function (tzObj)
{
   this.timeZoneObj = tzObj;
   
}

DateTimeObj.prototype.GetDateOnlyDateTime = function (isAddFactor)
{
   if (isAddFactor==null)
   {
    isAddFactor= false;
   }
   var ret = CreateNewDateFromMili(this.innerMiliSecs,this.timeZoneObj);
   var date = ret.GetDateForShow();
   var hours = ret.GetHoursForShow();
   var mins = ret.GetMinutesForShow();
   var secs = ret.GetSecondsForShow();
   ret = ret.AddHours(-1*hours);
   ret = ret.AddMinutes(-1*mins);
   ret = ret.AddSeconds(-1*secs);
   //var offset = date - ret.GetDateForShow();
   //ret = ret.AddHours(offset);
   var cmp = this.CompareDateForShowTo(ret);
   if (cmp!=0)
   {
      ret =ret.AddHours(cmp);
   }
   if (isAddFactor)
   {
       if (ret.GetHoursForShow() != 0)
       {
           var factor = -1;
           if (ret.GetDate()>date)
           {
                factor = 1;
           }
           while (ret.GetHoursForShow() != 0)
           {
              ret = ret.AddHours(factor);
           }
       }
   }
   return ret;
}

DateTimeObj.prototype.GetDateOnlyDateTimeAbsolute = function ()
{
   var ret = CreateNewDateFromMili(this.innerMiliSecs,this.timeZoneObj);
   ret = ret.AddHours(-1*ret.GetHours());
   ret = ret.AddMinutes(-1*ret.GetMinutes());
   ret = ret.AddSeconds(-1*ret.GetSeconds());
   return ret;
   
}

DateTimeObj.prototype.GenerateCreationString = function ()
{
   return 'CreateNewDateFromMili(' + this.innerMiliSecs +')';
   
}

DateTimeObj.prototype.AddSeconds = function (sec)
{
   return (CreateNewDateFromMili(this.innerMiliSecs + sec*1000,this.timeZoneObj));
   
}

DateTimeObj.prototype.AddMinutes = function (min)
{
   return (CreateNewDateFromMili(this.innerMiliSecs + min*MINUTE_IN_MILISECONDS,this.timeZoneObj));
   
}
DateTimeObj.prototype.AddHours = function (hour)
{
   return (CreateNewDateFromMili(this.innerMiliSecs + hour*HOUR_IN_MILISECONDS,this.timeZoneObj));
}

// add a day
// supports dls changes
// dir is either 1 for add day or -1 for substracting a day
DateTimeObj.prototype.AddDay = function (dir)
{
    var offset = this.GetTimeZoneOffset();
    var newDay = this.AddDays(dir);
    var newOffset = newDay.GetTimeZoneOffset();
    if (newOffset!=offset)
    {
            offset = newOffset-offset;
            newDay = newDay.AddHours(-1*offset);
    }
   /*var ret = CreateNewDateFromMili(this.innerMiliSecs);
   while (ret.GetDateForShow() == this.GetDateForShow())
   { // if still same day
     ret = ret.AddMinutes(dir*30);     
   }
   return (ret);*/
   return newDay;
}

DateTimeObj.prototype.AddDays = function (days)
{
   var ret = CreateNewDateFromMili(this.innerMiliSecs + days*DAY_IN_MILISECONDS,this.timeZoneObj);
   return (ret);
}


DateTimeObj.prototype.GetSeconds = function ()
{
   var dt = new Date();
   dt.setTime(this.innerMiliSecs );   
   return dt.getUTCSeconds();
}

DateTimeObj.prototype.GetMinutes = function ()
{
   var dt = new Date();
   dt.setTime(this.innerMiliSecs);
   return dt.getUTCMinutes();
}


DateTimeObj.prototype.GetHours = function ()
{
   var dt = new Date();
   dt.setTime(this.innerMiliSecs);
   return  dt.getUTCHours();
}


DateTimeObj.prototype.GetDate = function ()
{
   var dt = new Date();
   dt.setTime(this.innerMiliSecs);
   return dt.getUTCDate();
}

DateTimeObj.prototype.GetDay = function ()
{
   var dt = new Date();
   dt.setTime(this.innerMiliSecs);
   return dt.getUTCDay();
}

DateTimeObj.prototype.GetMonth = function ()
{
   var dt = new Date();
   dt.setTime(this.innerMiliSecs);
   return dt.getUTCMonth();
}

DateTimeObj.prototype.GetFullYear = function ()
{
   var dt = new Date();
   dt.setTime(this.innerMiliSecs);
   return dt.getUTCFullYear();
}

DateTimeObj.prototype.IsInDLS = function ()
{
  return (this.GetDLSOffset()!=0);
}

DateTimeObj.prototype.GetDLSIcon = function (top)
{
  var ret = "";
  if (top==null)
  {
    top = 2;
  }
  if (this.timeZoneObj.hasDayLightSavings)
  {
      ret = '';
      if (this.IsInDLS())
      {
        ret +='&nbsp;<img style="position:relative;top:'+top+'px" border="0" src="Images/sun_on.gif" title="Daylight saving time in effect" style="width: 14px; height:14px"></img>';
      }
      else
      {
        ret +='&nbsp;<span title ="Daylight saving time not in effect"></span> '; //'Images/sun_off.gif" title ="Daylight saving time not in effect" '
      }   
  }
  return ret;
}

DateTimeObj.prototype.GetDLSOffset = function ()
{
  var ret = 0;
  if (this.timeZoneObj.hasDayLightSavings)
  {
     if (this.timeZoneObj.dayLightSavings!=null)
     {
       var len = this.timeZoneObj.dayLightSavings.length;
       for (var i=0;i<len;i++)
       {
           var dlsObj = this.timeZoneObj.dayLightSavings[i];
           if ((this.innerMiliSecs >= dlsObj.startTimeMili) && (this.innerMiliSecs<dlsObj.endTimeMili))
           {
              ret = dlsObj.offset - this.timeZoneObj.timeZone;
           }
       }
     }    
  }  
  return ret;
}

DateTimeObj.prototype.GetTimeZoneOffset = function ()
{
  var ret = this.timeZoneObj.timeZone + this.GetDLSOffset();
  return ret;
}

DateTimeObj.prototype.IsPastDue = function ()
{
    var ret = false;
    var currTime = GetNowDateTime(this.timeZoneObj);
    if (currTime.CompareTo(this)==1)
    { // if bigger then past due
     ret = true;
    }
    return ret;
}

DateTimeObj.prototype.GetInnerMilisecondsForShow = function ()
{
   if (this.timeZoneObj.timeZone==null)
   {
       throw new Error('kakai');    
   }
   var ret = this.innerMiliSecs + (this.timeZoneObj.timeZone + this.GetDLSOffset()) * HOUR_IN_MILISECONDS;   
   return ret;
}

DateTimeObj.prototype.GetInnerMiliseconds = function ()
{
   if (this.timeZoneObj.timeZone==null)
   {
       throw new Error('kakai');    
   }
   var ret = this.innerMiliSecs;
   return ret;
}

DateTimeObj.prototype.GetSecondsForShow = function ()
{
   var dt = new Date();
   dt.setTime(this.GetInnerMilisecondsForShow());   
   return dt.getUTCSeconds();
}

DateTimeObj.prototype.GetMinutesForShow = function ()
{
   var dt = new Date();
   dt.setTime(this.GetInnerMilisecondsForShow());
   return dt.getUTCMinutes();
}


DateTimeObj.prototype.GetHoursForShow = function ()
{
   var dt = new Date();
   dt.setTime(this.GetInnerMilisecondsForShow());
   return dt.getUTCHours();
}

DateTimeObj.prototype.GetYearForShow = function ()
{
   if (this.m_yearForShow==-1)
   {
       var dt = new Date();
       dt.setTime(this.GetInnerMilisecondsForShow());
       this.m_yearForShow = dt.getFullYear();
   }
   return this.m_yearForShow;
}
DateTimeObj.prototype.GetDateForShow = function ()
{
   if (this.m_dateForShow==-1)
   {
       var dt = new Date();
       dt.setTime(this.GetInnerMilisecondsForShow());
       this.m_dateForShow = dt.getUTCDate();
   }
   return this.m_dateForShow;
}
DateTimeObj.prototype.GetDayForShow = function ()
{
   /*if (this.m_dateForShow==-1)
   {*/
       var dt = new Date();
       dt.setTime(this.GetInnerMilisecondsForShow());
       return dt.getUTCDay();
   /*}*/
   return this.m_dayForShow;
}
DateTimeObj.prototype.GetMonthForShow = function ()
{
   if (this.m_monthForShow==-1)
   {
       var dt = new Date();
       dt.setTime(this.GetInnerMilisecondsForShow());
       this.m_monthForShow = dt.getUTCMonth();
   }
   return this.m_monthForShow;
}

DateTimeObj.prototype.GetFullYearForShow = function ()
{
   if (this.m_fullYearForShow==-1)
   {
       var dt = new Date();
       dt.setTime(this.GetInnerMilisecondsForShow());
       this.m_fullYearForShow= dt.getUTCFullYear();
   }
   return this.m_fullYearForShow;
}

DateTimeObj.prototype.GetMonthName = function ()
{
   return this.MONTH_NAMES[this.GetMonthForShow()+12];
}

DateTimeObj.prototype.GetDayName = function ()
{
   return this.DAY_NAMES[this.GetDayForShow()+7];
}

DateTimeObj.prototype.GetClosestSundayDate = function ()
{
   ret = CreateNewDateFromMili(this.innerMiliSecs,this.timeZoneObj);
   ret.innerMiliSecs -= DAY_IN_MILISECONDS * ret.GetDayForShow();
   return ret;
}

DateTimeObj.prototype.GetClosestDayDate = function (day)
{
   ret = CreateNewDateFromMili(this.innerMiliSecs,this.timeZoneObj);
   ret.innerMiliSecs -= DAY_IN_MILISECONDS * ret.GetDayForShow();
   ret = ret.AddDays(day);
   if (ret.CompareTo(this)==1)
   {
       ret = ret.AddDays(-7);
   }
   return ret;
}

DateTimeObj.prototype.GetNextDay = function ()
{
   var date = this.GetDateForShow();
   var ret = this.GetDateOnlyDateTime(true);//.AddDays(1);
   var isSame = false;
   while (ret.GetDateForShow() == date)
   {
     ret = ret.AddHours(date);
     isSame = true;
   }
   ret = ret.GetDateOnlyDateTime(true);//.AddDays(1);
   if (isSame)
   {
    //alert (ret+'_'+this);
   }
   return ret;
}

DateTimeObj.prototype.GetDateTimeIndicator = function ()
{  
   return (this.GetFullYearForShow().toString() +''+ this.GetMonthForShow().toString() + '' +this.GetDateForShow().toString());
}
DateTimeObj.prototype.CompareTo = function (otherDateTimeObj)
{  
   var diff = this.innerMiliSecs - otherDateTimeObj.innerMiliSecs;
   if (diff > 0)
   {
      return 1;
   }
   if (diff < 0)
   {
      return -1;
   }
   return 0;
}

DateTimeObj.prototype.CompareDateForShowTo = function (otherDateTimeObj)
{
   var thisDate = Date.UTC( this.GetFullYearForShow(), this.GetMonthForShow(), this.GetDateForShow(),0,0,0);  
   var otheDate = Date.UTC( otherDateTimeObj.GetFullYearForShow(), otherDateTimeObj.GetMonthForShow(), otherDateTimeObj.GetDateForShow(),0,0,0);
   if (thisDate > otheDate)
   {
      return 1;
   }
   if (thisDate < otheDate)
   {
      return -1;
   }
   return 0;
}

DateTimeObj.prototype.IsEqualToJSDate = function (jsDate)
{
   if (this.GetFullYearForShow() == jsDate.getFullYear())
   {
       if (this.GetMonthForShow() == jsDate.getMonth())
       {
           if (this.GetDateForShow() == jsDate.getDate())
           {
                return true;
           }
        
       }
   }
   return false;
}

DateTimeObj.prototype.IsEqualToJSUTCDate = function (jsDate)
{
   if (this.GetFullYearForShow() == jsDate.getUTCFullYear())
   {
       if (this.GetMonthForShow() == jsDate.getUTCMonth())
       {
           if (this.GetDateForShow() == jsDate.getUTCDate())
           {
                return true;
           }
        
       }
   }
   return false;
}

DateTimeObj.prototype.IsEqualToDate = function (date)
{
   if (this.GetFullYearForShow() == date.GetFullYearForShow())
   {
       if (this.GetMonthForShow() == date.GetMonthForShow())
       {
           if (this.GetDateForShow() == date.GetDateForShow())
           {
                return true;
           }
        
       }
   }
   return false;
}


DateTimeObj.prototype.LowerOrEqual = function (otherDateTimeObj)
{
   var comp = this.CompareTo(otherDateTimeObj);
   var ret = false;
   if ((comp==0) || (comp==-1))
   {
      ret = true;
   }
   return ret;
}

DateTimeObj.prototype.GreaterOrEqual = function (otherDateTimeObj)
{
   var comp = this.CompareTo(otherDateTimeObj);
   var ret = false;
   if ((comp==0) || (comp==1))
   {
      ret = true;
   }
   return ret;
}
/*DateTimeObj.prototype.IsInDateBoundaries = function (lower,upper)
{
  var ret = false;
  var startDate = lower.GetDateOnlyDateTime();
  var endDate = upper.GetDateOnlyDateTime().AddHours(23).AddMinutes(59);
   if (this.GreaterOrEqual(lower)) && (this.LowerOrEqual(upper))
   {
      ret = true;
   }
   return ret;
}*/

DateTimeObj.prototype.toString = function (isShowTz)
{
   if (isShowTz==null)
   {
        isShowTz=true;
   }
   var ret = this.formatDate('EE, MMM dd, yyyy') +' ' + GetTimeStringByPrefrecesByDate(this,currUserData);
   if (isShowTz)
   {
        ret += '('+this.timeZoneObj+')';
   }
   return ret;
}

DateTimeObj.prototype.toStringAbsolute = function ()
{
   var ret = this.formatDateAbsolute('EE, MMM dd, yyyy') +' ' + GetTimeStringByPrefrecesByDate(this,currUserData);
   return ret;
}


DateTimeObj.prototype.MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
DateTimeObj.prototype.DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
DateTimeObj.prototype.LZ = function (x){return(x<0||x>9?"":"0")+x}

// ------------------------------------------------------------------
// formatDate (format)
// Returns a date in the output format specified.
// The format string uses the same abbreviations as in getDateFromFormat()
// ------------------------------------------------------------------
// Field        | Full Form          | Short Form
// -------------+--------------------+-----------------------
// Year         | yyyy (4 digits)    | yy (2 digits), y (2 or 4 digits)
// Month        | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
//              | NNN (abbr.)        |
// Day of Month | dd (2 digits)      | d (1 or 2 digits)
// Day of Week  | EE (name)          | E (abbr)
// Hour (1-12)  | hh (2 digits)      | h (1 or 2 digits)
// Hour (0-23)  | HH (2 digits)      | H (1 or 2 digits)
// Hour (0-11)  | KK (2 digits)      | K (1 or 2 digits)
// Hour (1-24)  | kk (2 digits)      | k (1 or 2 digits)
// Minute       | mm (2 digits)      | m (1 or 2 digits)
// Second       | ss (2 digits)      | s (1 or 2 digits)
// AM/PM        | a                  |
//
// NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
// Examples:
//  "MMM d, y" matches: January 01, 2000
//                      Dec 1, 1900
//                      Nov 20, 00
//  "M/d/yy"   matches: 01/20/00
//                      9/2/00
//  "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
// ------------------------------------------------------------------
DateTimeObj.prototype.formatDate = function (format)
{
	format=format+"";
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=this.GetFullYearForShow()+"";
	var M=this.GetMonthForShow()+1;
	var d=this.GetDateForShow();
	var E=this.GetDayForShow();
	var H=this.GetHoursForShow();
	var m=this.GetMinutesForShow();
	var s=this.GetSecondsForShow();
	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
	// Convert real date parts into formatted versions
	var value=new Object();
	if (y.length < 4) {y=""+(y-0+1900);}
	value["y"]=""+y;
	value["yyyy"]=y;
	value["yy"]=y.substring(2,4);
	value["M"]=M;
	value["MM"]=this.LZ(M);
	value["MMM"]=this.MONTH_NAMES[M-1];
	value["NNN"]=this.MONTH_NAMES[M+11];
	value["d"]=d;
	value["dd"]=this.LZ(d);
	value["E"]=this.DAY_NAMES[E+7];
	value["EE"]=this.DAY_NAMES[E];
	value["H"]=H;
	value["HH"]=this.LZ(H);
	if (H==0){value["h"]=12;}
	else if (H>12){value["h"]=H-12;}
	else {value["h"]=H;}
	value["hh"]=this.LZ(value["h"]);
	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
	value["k"]=H+1;
	value["KK"]=this.LZ(value["K"]);
	value["kk"]=this.LZ(value["k"]);
	if (H > 11) { value["a"]="pm"; }
	else { value["a"]="am"; }
	value["m"]=m;
	value["mm"]=this.LZ(m);
	value["s"]=s;
	value["ss"]=this.LZ(s);
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
		}
	return result;
	}


DateTimeObj.prototype.formatDateAbsolute = function (format)
{
	format=format+"";
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=this.GetFullYear()+"";
	var M=this.GetMonth()+1;
	var d=this.GetDate();
	var E=this.GetDay();
	var H=this.GetHours();
	var m=this.GetMinutes();
	var s=this.GetSeconds();
	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
	// Convert real date parts into formatted versions
	var value=new Object();
	if (y.length < 4) {y=""+(y-0+1900);}
	value["y"]=""+y;
	value["yyyy"]=y;
	value["yy"]=y.substring(2,4);
	value["M"]=M;
	value["MM"]=this.LZ(M);
	value["MMM"]=this.MONTH_NAMES[M-1];
	value["NNN"]=this.MONTH_NAMES[M+11];
	value["d"]=d;
	value["dd"]=this.LZ(d);
	value["E"]=this.DAY_NAMES[E+7];
	value["EE"]=this.DAY_NAMES[E];
	value["H"]=H;
	value["HH"]=this.LZ(H);
	if (H==0){value["h"]=12;}
	else if (H>12){value["h"]=H-12;}
	else {value["h"]=H;}
	value["hh"]=this.LZ(value["h"]);
	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
	value["k"]=H+1;
	value["KK"]=this.LZ(value["K"]);
	value["kk"]=this.LZ(value["k"]);
	if (H > 11) { value["a"]="pm"; }
	else { value["a"]="am"; }
	value["m"]=m;
	value["mm"]=this.LZ(m);
	value["s"]=s;
	value["ss"]=this.LZ(s);
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
		}
	return result;
	}

DateTimeObj.prototype.GetWeek = function(startWeekDay) {
var currDate = this.GetClosestDayDate(startWeekDay);
var onejan = new Date(currDate.GetFullYear(),0,1);
var curDateObj=new Date(currDate.GetFullYear(),currDate.GetMonth(),currDate.GetDate());
return Math.ceil((((curDateObj - onejan) / 86400000) + onejan.getDay())/7);
}

// ------------------------------------------------------------------
// Utility functions for parsing in getDateFromFormat()
// ------------------------------------------------------------------
function _isInteger(val) {
	var digits="1234567890";
	for (var i=0; i < val.length; i++) {
		if (digits.indexOf(val.charAt(i))==-1) { return false; }
		}
	return true;
	}
function _getInt(str,i,minlength,maxlength) {
	for (var x=maxlength; x>=minlength; x--) {
		var token=str.substring(i,i+x);
		if (token.length < minlength) { return null; }
		if (_isInteger(token)) { return token; }
		}
	return null;
	}
	
// ------------------------------------------------------------------
// getDateFromFormat( date_string , format_string )
//
// This function takes a date string and a format string. It matches
// If the date string matches the format string, it returns the 
// getTime() of the date. If it does not match, it returns 0.
// ------------------------------------------------------------------
function getDateFromFormat(val,format) {
	val=val+"";
	format=format+"";
	var i_val=0;
	var i_format=0;
	var c="";
	var token="";
	var token2="";
	var x,y;
	var now=new Date();
	var year=now.getFullYear();
	var month=now.getMonth()+1;
	var date=1;
	var hh=now.getHours();
	var mm=now.getMinutes();
	var ss=now.getSeconds();
	var ampm="";
	
	while (i_format < format.length) {
		// Get next token from format string
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		// Extract contents of value based on format token
		if (token=="yyyy" || token=="yy" || token=="y") {
			if (token=="yyyy") { x=4;y=4; }
			if (token=="yy")   { x=2;y=2; }
			if (token=="y")    { x=2;y=4; }
			year=_getInt(val,i_val,x,y);
			if (year==null) { return 0; }
			i_val += year.length;
			if (year.length==2) {
				if (year > 70) { year=1900+(year-0); }
				else { year=2000+(year-0); }
				}
			}
		else if (token=="MMM"||token=="NNN"){
			month=0;
			for (var i=0; i< DateTimeObj.prototype.MONTH_NAMES.length; i++) {
				var month_name=DateTimeObj.prototype.MONTH_NAMES[i];
				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
					if (token=="MMM"||(token=="NNN"&&i>11)) {
						month=i+1;
						if (month>12) { month -= 12; }
						i_val += month_name.length;
						break;
						}
					}
				}
			if ((month < 1)||(month>12)){return 0;}
			}
		else if (token=="EE"||token=="E"){
			for (var i=0; i<DAY_NAMES.length; i++) {
				var day_name=DAY_NAMES[i];
				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
					i_val += day_name.length;
					break;
					}
				}
			}
		else if (token=="MM"||token=="M") {
			month=_getInt(val,i_val,token.length,2);
			if(month==null||(month<1)||(month>12)){return 0;}
			i_val+=month.length;}
		else if (token=="dd"||token=="d") {
			date=_getInt(val,i_val,token.length,2);
			if(date==null||(date<1)||(date>31)){return 0;}
			i_val+=date.length;}
		else if (token=="hh"||token=="h") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>12)){return 0;}
			i_val+=hh.length;}
		else if (token=="HH"||token=="H") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>23)){return 0;}
			i_val+=hh.length;}
		else if (token=="KK"||token=="K") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>11)){return 0;}
			i_val+=hh.length;}
		else if (token=="kk"||token=="k") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>24)){return 0;}
			i_val+=hh.length;hh--;}
		else if (token=="mm"||token=="m") {
			mm=_getInt(val,i_val,token.length,2);
			if(mm==null||(mm<0)||(mm>59)){return 0;}
			i_val+=mm.length;}
		else if (token=="ss"||token=="s") {
			ss=_getInt(val,i_val,token.length,2);
			if(ss==null||(ss<0)||(ss>59)){return 0;}
			i_val+=ss.length;}
		else if (token=="a") {
			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="am";}
			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="pm";}
			else {return 0;}
			i_val+=2;}
		else {
			if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
			else {i_val+=token.length;}
			}
		}
	// If there are any trailing characters left in the value, it doesn't match
	if (i_val != val.length) { return 0; }
	// Is date valid for month?
	if (month==2) {
		// Check for leap year
		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
			if (date > 29){ return 0; }
			}
		else { if (date > 28) { return 0; } }
		}
	if ((month==4)||(month==6)||(month==9)||(month==11)) {
		if (date > 30) { return 0; }
		}
	// Correct hours value
	if (hh<12 && ampm=="pm") { hh=hh-0+12; }
	else if (hh>11 && ampm=="am") { hh-=12; }
	var newdate=new Date(year,month-1,date,hh,mm,ss);
	return newdate.getTime();
	}

function CalcWeekFromDate(startDate,dateInWeek)
{
    //var currDate = startDate.GetClosestDayDate(currUserData.userStartWeekDay);
    return dateInWeek.GetWeek(currUserData.userStartWeekDay);
//    alert(dateInWeek.GetWeek(currUserData.userStartWeekDay));
//    alert(currUserData.userStartWeekDay);
//    //alert(currDate);
//    //alert(dateInWeek);
//    var weekIdx = 0;
//    while (currDate.LowerOrEqual(dateInWeek))
//    {
//        currDate = currDate.AddDays(7);
//        weekIdx++;
//    }
//    if (currUserData.userStartWeekDay>0)
//    {
//        weekIdx--;
//    }
//    else
//    {
//    }
//    if (currUserData.userStartWeekDay==0)
//    {
//        weekIdx--;
//    }
//    return weekIdx;
}

   
function LastDayOfMonth(Year, Month)
{
    return(new Date((new Date(Year, Month+1,1))-1)).getDate();
}