
Dates = {
	date: function(y, m, d) {
   		this.year = 1*y;
   		this.month = 1*m;
   		this.day = 1*d;
  		this.days = Dates.YMDdate2int(1*y, 1*m, 1*d);
	},
	
	currentDate: function() {
		var now = new Date();
		return new this.date(now.getFullYear(), now.getMonth()+1, now.getDate());
	},
	
	dow: function(i) {
 		return ((i%7)+1);
	},
	
	dowDate: function(date) {
		return this.dow(date.days);
	},

	dowYMD: function(y, m, d) {
		return this.dowDate(new this.date(y, m, d));
	},
	
	date2int: function(date) {
		return (date.days);
	},
		
	YMDdate2int: function(y,m,d) {
		yy=(y-1)*365 + div((y-1),4) - div((y-1),100) + div((y-1),400);
		mm=(m-1)*30 + div(m,2) - 2*div(m,3)+ 2*div(m,6) + 3*div(m,9) - div(m,10) + div(m,11) - div(m,12);
		dd=1*d+1*(m>=3 && this.isLeapYear(y)?0:-1);
		
		return (1*yy+1*mm+1*dd);
	},
	
	int2date: function (i) {
		var y=(1+div((i-div((i+183),1461)+div((i+183),36524)-div((i+183),146096)),365));
  
 		var j=i-this.YMDdate2int(y,1,1);
		var m=(
			this.isLeapYear(y)
			?
			(1+div((j-1-div(j,30)+div(j,60)-div(j,89)-div(j,120)-div(j,151)-div(j,212)-div(j,243)+div(j,274)-div(j,304)),29))
			:
			(1+div((j-1-div(j,29)-div(j,30)+div(j,59)-div(j,89)+div(j,90)-div(j,118)-div(j,119)+div(j,120)-div(j,149)-div(j,150)+div(j,151)-div(j,180)-div(j,211)-div(j,242)-div(j,303)),28))
		);
 		
 		if (m==0)
 			m=1;
 
		var d=i-this.YMDdate2int(y,m,1)+1;
 
		return new this.date(y,m,d);
	},
	
	isLeapYear: function(y) {
		return (((y % 100 == 0) && (y % 400 == 0)) || ((y % 100 != 0) && (y % 4 == 0)) ? true : false);
	},
	
	getMonthLength: function(m,y) {
		if (m==1 || m==3 || m==5 || m==7 || m==8 || m==10 || m==12)
   			return 31;
   		else if (m==4 || m==6 || m==9 || m==11)
   			return 30;
   		else {
	  		if (this.isLeapYear(y))
    		  	return 29;
			else
				return 28; 
		}
	}
}

// div shorthand method
function div(a,b) {
   return (Math.floor(a/b));
}