function Duration(pm, years, months, days, hours, minutes, seconds, fraction){
		 
	var giYearMill = 31536000000;	var giMonthMill = 2592000000;
	var giDayMill = 86400000;	var giHourMill = 3600000;
	var giMinMill = 60000;	var giSecMill = 1000;

	this.pm = pm;
	this.years = (years?years:0)*1;
	this.months = (months?months:0)*1;
	this.days = (days?days:0)*1;
	this.hours = (hours?hours:0)*1;
	this.minutes = (minutes?minutes:0)*1;
	this.seconds = (seconds?seconds:0)*1;
	this.fraction = fraction*1;
	if(fraction != undefined){
	   this.milliseconds = eval('0.'+fraction) * 100;
	}
	else {
	   this.milliseconds = 0;
	}
	this.mask = ((this.years?1:0)<<6) + ((this.months?1:0)<<5) + ((this.days?1:0)<<4) + ((this.hours?1:0)<<3) + ((this.minutes?1:0)<<2) + ((this.seconds?1:0)<<1) + (this.milliseconds?1:0);
	this.Seconds = function(){
	          if (this.years || this.months){
			          return Number.NaN;
			  }	
		
		return (this.days*giDayMill + this.hours*giHourMill + this.minutes*giMinMill + this.seconds*giSecMill)*(this.pm=="-"?-1:1);

	}
	
	
	this.validDuration = function(d){
        var parts;
        var re = new RegExp("^([\-])?P(([0-9]+)Y)?(([0-9]+)M)?(([0-9]+)D)?((T)?(([0-9]+)H)?(([0-9]+)M)?((([0-9]+)(\.([0-9]+))?)S)?)?$");
        if(d=="") return Number.NaN;
        if (parts = re.exec(d)){
                
                if ((/T$/.exec(d)) || (parts[9] == "T" && parts[11]+parts[13]+parts[16]+parts[18]== ""))// ~(:+(|) duh!!!
                       return Number.NaN;
                return new Duration(parts[1]?parts[1]:"", parts[3], parts[5], parts[7], parts[11], parts[13], parts[16], parts[18]);				
        }
        return Number.NaN;
	 }	 
	 
	this.validDate = function(date){
			var parts;
			var oDate = new Date(-62135596800000); // Mon Jan 1 00:00:00 UTC 1
			//	case "xs:dateTime": //(CCYY-MM-DDThh:mm:ss) 2006-10-12T12:00:00.000+02:00
					var re = new RegExp("^([0-9]{4})-([0-9]{2})-([0-9]{2})(T([0-9]{2})(:([0-9]{2})(:([0-9]{2}))(\.([0-9]+))?)?)?(Z)?([\+\-][0-9]{2}:[0-9]{2})?$");
					if (parts=re.exec(date)){
						if (parts[re.length-2] == "Z"){
							oDate.setFullYear(parts[1], parts[2]-1, parts[3]);
							oDate.setHours(parts[5], parts[7], parts[9]);
							oDate.setMinutes(oDate.getMinutes()-oDate.getTimezoneOffset());
							gsSuppliedFormat = "xs:dateTime";
							return oDate;
						}else{
							oDate.setFullYear(parts[1], parts[2]-1, parts[3]);
							oDate.setHours(parts[5], parts[7], parts[9]);
							gsSuppliedFormat = "xs:dateTime";
							return oDate;
						}
					}
			return false;
		}	

	this.formatDate = function(oDate, format){
	
		if (oDate == Number.NaN)return Number.NaN;
		switch(format){
			case "xs:dateTime": //(CCYY-MM-DDThh:mm:ss)
				var tzo = oDate.getTimezoneOffset(); 
				return oDate.getFullYear() + "-" + pad(oDate.getMonth()+1) + "-" + pad(oDate.getDate()) + "T" +
					   pad(oDate.getHours()) + ":" + pad(oDate.getMinutes()) + ":" + pad(oDate.getSeconds()) + (tzo < 0?"-":"+") + pad(Math.abs(tzo/60)) + ":" + pad(tzo % 60);
				break;
			}	
		return false;
	}	
	
	function pad(v){
		return (v<10?"0"+v:v);
	}	
	
	this.formatDuration = function(du){
		if (typeof(du) == "object"){
			var pm = du.pm;
			var y = du.years;
			var m = du.months;
			var d = du.days;
			var h = du.hours;
			var n = du.minutes;
			var s = du.seconds + du.milliseconds/1000;
			
			if (y+m+d+h+n+s == 0)
				return 'P0S';
			return pm + "P" + 
					(y!=0?y + "Y":'') + 
					(m!=0?m + "M":'') + 
					(d!=0?d + "D":'') + 
					(h+n+s!=0?"T":'') +
					(h!=0?h + "H":'') + 
					(n!=0?n + "M":'') + 
					(s!=0?s + "S":'');
		}else{
			var pm = (du<0?'-':'');
			du = Math.abs(du);
			var d = Math.floor((du) / giDayMill);
			var h = Math.floor((du % giDayMill) / giHourMill);
			var n = Math.floor((du % giHourMill) / giMinMill);
			var s = Math.floor((du % giMinMill) / giSecMill) + (du % giSecMill)/1000;
			if(du==0){
			return pm + "PT0.000S" ;
			}
			else{
			return pm + "P" + 
					(d!=0?d + "D":'') + 
					(h+n+s!=0?"T":'') +
					(h!=0?h + "H":'') + 
					(n!=0?n + "M":'') + 
					(s!=0?s + "S":'');
			}
		}
}	

}