UNPKG

@xassist/xassist-date

Version:

helper functions for date manipulation

834 lines (780 loc) 27.2 kB
/** * @preserve * https://github.com/GregBee2/xassist-date.git Version 1.2.2. * Copyright 2018 Gregory Beirens. * Created on Tue, 17 Apr 2018 10:42:12 GMT. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@xassist/xassist-object')) : typeof define === 'function' && define.amd ? define(['exports', '@xassist/xassist-object'], factory) : (factory((global.xa = global.xa || {}),global.xa)); }(this, (function (exports,xassistObject) { 'use strict'; //var { object } =require("@xassist/xassist-object"); function getDecimal(num){ return+((num<0?"-.":".")+num.toString().split(".")[1])||0 } var _durationRegexp=[ {key:"year",re: /(-?\d*(?:[.,]\d*)?)(?:[ ]?y|Y|years?|Years?)(?![a-zA-z])/g}, //years component {key:"month",re: /(-?\d*(?:[.,]\d*)?)(?:[ ]?M|months?|Months?)(?![a-zA-z])/g}, //months component {key:"day",re: /(-?\d*(?:[.,]\d*)?)(?:[ ]?d|D|days?|Days?)(?![a-zA-z])/g}, //days component {key:"hour",re: /(-?\d*(?:[.,]\d*)?)(?:[ ]?h|H|hours?|Hours?)(?![a-zA-z])/g}, //hours component {key:"minute",re: /(-?\d*(?:[.,]\d*)?)(?:[ ]?m|mins?|Mins?|minutes?|Minutes?)(?![a-zA-z])/g}, //minutes component {key:"second",re: /(-?\d*(?:[.,]\d*)?)(?:[ ]?s|S|secs?|Secs?|seconds?|Seconds?)(?![a-zA-z])/g}, //seconds component {key:"millisecond",re: /(-?\d*(?:[.,]\d*)?)(?:[ ]?ms|millis?|m[sS]ecs?|m[sS]econds?|milli[sS]ecs?|milli[sS]econds?)(?![a-zA-z])/g}, //milliseconds component ]; /* regexp explanation for each component eg for year / //start regexp ( //capturing group 1 number of years -? //optional negative number \d* //zero or more digits (?: //non capturing group [.,] //matches single character (point or ,) \d* //zero or more digits )? //optional could be omitted ) //capturing group finished (matches on 1.25|0.25|1000|1.|.|.5 or with a comma.) (?: //non capturing group (years) [ ]? //optional space y|Y|years?|Years? //y or Y or year or years or Year or Years ) //closes group for (y||Y||year||years||Year||Years) (?![a-zA-z]) //negative lookahead everything except a-z or A-Z /g //global match */ function _parseDurationString(d,durStr){ var matchMade; //parse string //eg 1y1M1d1h1m1s1ms //abbrev for(var i=0,len=_durationRegexp.length;i<len;i++){ //for multiple matches on same regegexp we could use exec while (matchMade = _durationRegexp[i].re.exec(durStr)) { d[_durationRegexp[i].key]+=parseFloat((matchMade[1]||"0").replace(",",".")); } } return d; } var duration=function(){ return new XaDuration([].slice.call(arguments)); }; function XaDuration(initArray){ this.year=0; this.month=0; this.day=0; this.hour=0; this.minute=0; this.second=0; this.millisecond=0; this.normalized=false; //this.dayReserve=0; //hold converted month decimals in days, to calculate when really needed this.init(initArray); } XaDuration.prototype._keyOrder=[ 'year', 'month', 'day', 'hour', 'minute', 'second', 'millisecond' ]; XaDuration.prototype.init=function(a){ if (a.length===1){ if(typeof a[0]==="string"){ _parseDurationString(this,a[0]); } else if(typeof a[0]==="number"){ //milliseconds is default value this.millisecond+=a[0]; } else if(typeof a[0]==="object"){ xassistObject.object(this).mergeUnique(a[0]); } } if(a.length>1){ a.forEach(function(val,i){ //console.log(val,i,wantedKeys[i],this[wantedKeys[i]]) if(i<this._keyOrder.length&&typeof val==="number"){ this[this._keyOrder[i]]+=val; } },this); } }; /* we should normalize the floating values to do calculations with dates this works for - s=>milisecs (*1000) - min=>sec (*60) - hr=>min (*60) - day=>hr (*24) - year=>month (*12) exception -month=>day (*30 or *31 or *28 or even *29) So there is a break in normalization between day and month setting apart month and year! */ var _conversionCoefficients={ year:{ coeff:7/(30.436875*12), exactType:"big" }, month:{ coeff:7/30.436875, exactType:"big" }, week:{ coeff:1, exactType:"small" }, day:{ coeff:7, exactType:"small" }, hour:{ coeff:168, exactType:"small" }, minute:{ coeff:10080, exactType:"small" }, second:{ coeff:604800, exactType:"small" }, millisecond:{ coeff:604800000, exactType:"small" } }; XaDuration.prototype.normalize=function(exact){ exact=(typeof exact==="undefined"?true:!!exact); //first we normalize up to upscale the factors thats needed like 12months becomes 1 year this.normalizeUp(exact); //the only factor that is decimal is the one from day to month so //after upscaling the only attribute potentially remaining decimal is day //now we can normalize down to eliminate decimals if(!this.normalized){ this.normalizeDown(exact); //this could introduce other scaling factors that should be upscaled (added hours so hours fall above 24 or lower) //since those all fall lower then day we should only once scale up if necessary (but we put true to be sure to not change months this.normalizeUp(true); } }; XaDuration.prototype.normalizeDown=function(exact){ var key,dec,nextKey,factor; exact=(typeof exact==="undefined"?true:!!exact); for (var i=0,len=this._keyOrder.length;i<len;i++){ key=this._keyOrder[i]; nextKey=this._keyOrder[i+1]; if(nextKey){ factor=this.getConversionFactor(key,nextKey); if(!exact||factor.exact){ dec=getDecimal(this[key]); this[key]=this[key]-dec; this[nextKey]+=dec*factor.factor; } } } //month is only one that can be decimal because only conversion thaht can be skipped with exact //we should not check millisecond because it is allowed to be decimal this.normalized=((getDecimal(this.month))===0); return this; }; XaDuration.prototype.normalizeUp=function(exact){ var key,nextKey,factor,oldVal,i=this._keyOrder.length,normalized=true; exact=(typeof exact==="undefined"?true:!!exact); while(i--){ key=this._keyOrder[i]; nextKey=this._keyOrder[i-1]; if(nextKey){ factor=this.getConversionFactor(nextKey,key); if(!exact||factor.exact){ oldVal=this[key]; this[key]=oldVal%factor.factor; this[nextKey]+=(oldVal-this[key])/factor.factor; } } if(i!==this._keyOrder.length-1){ normalized=normalized&&((this[key]*10%10/10)===0); } } this.normalized=normalized; return this; }; XaDuration.prototype.getConversionFactor=function(fromUnit,toUnit){ if(_conversionCoefficients.hasOwnProperty(fromUnit)&&_conversionCoefficients.hasOwnProperty(toUnit)){ return { factor:(_conversionCoefficients[toUnit].coeff/_conversionCoefficients[fromUnit].coeff), exact:(_conversionCoefficients[toUnit].exactType===_conversionCoefficients[fromUnit].exactType) } } else{ throw new TypeError("Invalid unit conversion type"); } }; XaDuration.prototype.valueOf=function(){ //returns number of milliseconds var result=0,key; for (var i=0,len=this._keyOrder.length;i<len;i++){ key=this._keyOrder[i]; result+=(this.getConversionFactor(key,"millisecond").factor*this[key]); } return result }; XaDuration.prototype.toString=function(){ var result=[],key,v=this.valueOf(),dur=duration(Math.abs(v)); dur.normalize(false); for (var i=0,len=this._keyOrder.length;i<len;i++){ key=this._keyOrder[i]; if(dur[key]!==0){ result.push(dur[key]+" "+key+(dur[key]>1?"s":"")); } } if(v<0){ result.push("ago"); } return result.join(' ')+"."; }; XaDuration.prototype.format=function(tolerance){ //tolerance is the relative tolerance that may be accepted in the string representation //tolerance is a percentage eg 0.01=1% and should be given as a numeric value<1 //if tolerance is given as 1 just the largest component //decimals are never given 3.5 years is represented as 3 years 6 months var result=[],key, v=this.valueOf(), absV=Math.abs(v), dur=duration(absV), //clone duration currentVal=0, relError=1; if(!tolerance){ return this.toString(); } tolerance=Math.abs(tolerance); tolerance=tolerance>1?1:tolerance; dur.normalize(false); for (var i=0,len=this._keyOrder.length;i<len&&relError>=tolerance;i++){ key=this._keyOrder[i]; if(dur[key]!==0){ currentVal+=dur[key]*this.getConversionFactor(key,"millisecond").factor; result.push(dur[key]+" "+key+(dur[key]>1?"s":"")); relError=1-currentVal/absV; } } //check if we could lower the relError by adding 1 to last found key (ex. rounding 3.5 years to 4) currentVal+=1*this.getConversionFactor(key,"millisecond").factor; if(relError>=(-1+currentVal/absV)){ //new relative error is negative because we are rounding up result.push(result.pop().split(" ").map(function(v,i){return (i==0?+v+1:v)}).join(" ")); } if(v<0){ result.push("ago"); } return result.join(' ')+"."; }; XaDuration.prototype.addDuration=function(dur){ var key,i,len; for (i=0, len=this._keyOrder.length;i<len;i++){ key=this._keyOrder[i]; if(dur.hasOwnProperty(key)&&typeof dur[key]==="number"){ this[key]+=dur[key]; } } return this; }; XaDuration.prototype.removeIntervalOfType=function(type,value){ if(~this._keyOrder.indexOf(type) ){ value=(typeof value==="number"?value:this[type]); this[type]-=value; return value; } else{ return 0; //throw typeError("Invalid interval type"); } }; XaDuration.prototype.normalizeMonth=function(numberOfDays){ var dec=getDecimal(this.month); this.month=this.month-dec; this.day+=numberOfDays*dec; return this.normalizeDown(); }; var _dateDict = { days:{ defaultKey:"long", "abbreviation" : ["S", "M", "T", "W", "T", "F", "S"], "short":["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], "long":["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] }, month:{ defaultKey:"long", "abbreviation" : ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"], "short": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], "long": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] } }, _leapYear=function(year) { //year not divisible by 4 => no leapyear (year % 4 == year & 3 (bitwise AND x%2^n===x&2^(n-1) bit wise and) //else: year not divisible by 100 => leapyear (year % 4 => check year%25 //else year divisble by 400 => leapyear ( (year %400) knwoing that year%25==0=>year%16 or year & 15) year=((typeof year==="undefined")?new Date().getFullYear():year); if(year>0||year<0){ return ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0)); } return undefined; }, _maxNumberofDays=function(month,year){ var leap; month=((typeof month==="undefined")?new Date().getMonth()+1:month); if(month===2){ leap=_leapYear(year); return (typeof leap==="undefined"?leap:(leap?29:28)) } else { return [31,28,31,30,31,30,31,31,30,31,30,31][month-1] } }, _validDate = function (d) { if (Object.prototype.toString.call(d) === "[object Date]") { // it is a date if (isNaN(d.getTime())) { // d.valueOf() could also work // date is not valid return false; } else { // date is valid return true; } } else { // not a date return false; } }, _dateRegExp=/^(\d{4}|\d{2}|[1-2]?\d{1}|3[0-1])[-/\\.](0?[1-9]|[1-2]\d{1}|3[0-1])[-/\\.](\d{4}|\d{2}|[1-2]?\d{1}|3[0-1])(?:[T ]([0-1]\d|2[0-3]):([0-5]\d)(?::([0-5]\d)(?:[.,](\d*)?)?)?)?$/i; /*regexp for datetime matching ^ //strings starts with ( //capturing group 1 (year or day) \d{4} //YYYY | //or \d{2} // YY or DD (01-31), difference not captured | //or [1-2]?\d{1} // D (1-29) ! 0 is allowed | //or 3[0-1] // D (30-31) ) [ //date-split:match single character from list - //dash / //forward slash \\ //back slash escaped . //point ] //end list ( //capturing group 2 (month) 0?[1-9] //optional 0 and 1-9 (1-9 or 01-09) | [1-2]?\d{1} // D (1-29) ! 0 is allowed | //or 3[0-1] // D (30-31) ) [ //date-split:match single character from list - //dash / //forward slash \\ //back slash escaped . //point ] //end list ( //capturing group 3 (year or day) \d{4} //YYYY | //or \d{2} // YY or DD (01-31), difference not captured | //or [1-2]?\d{1} // D (1-29) ! 0 is allowed | //or 3[0-1] // D (30-31) ) (?: //non capturing group (time) [T ] //1 character from list (T or space) ( //captruing group 4: hour [0-1]\d|2[0-3] //00-19 or 20-23 ) : //matches colon ":" ( //capturing group 5: minutes [0-5]\d //00-59 ) (?: //non capturing group (seconds and milliseconds) : //matches colon ":" ( //capturing group 6: seconds [0-5]\d //00-59 ) (?: //non capturing group (milliseconds) [.,] //matches single character (point or ,) ( //capturing group 7 \d* //any number of digits )? //optional could be omitted )? //optional could be omitted )? //optional could be omitted )? //optional, could be omitted $ //string end here */ //date functionality //date functionality var _getWeekDay= function (/*index,*/type, startindexOfWeek, zeroBased) { var onDateObj=0,index; if (this && this.constructor && this.constructor.name==="XaDate") { onDateObj=1; } index = (onDateObj?this.getDay():arguments[0]||0); type = (""+arguments[1-onDateObj]||_dateDict.days.defaultKey).toLowerCase(); startindexOfWeek = (onDateObj?0:arguments[2]||0); zeroBased = (onDateObj?true:!!(typeof arguments[3]!=="undefined"? arguments[3]:true)); index =((index - (zeroBased ? 0 : 1) + startindexOfWeek) % 7); type=(!_dateDict.days.hasOwnProperty(type)?_dateDict.days.defaultKey:type); index=(index<0?7+index:index); return _dateDict.days[type][index]; }; var _getMonth=function (/*index,*/type, zeroBased) { var onDateObj=0,index; if (this &&this.constructor && this.constructor.name==="XaDate") { onDateObj=1; } index = (onDateObj?this.getMonth():arguments[0]||0); type = (""+arguments[1-onDateObj]||_dateDict.month.defaultKey).toLowerCase(); type=(!_dateDict.month.hasOwnProperty(type)?_dateDict.month.defaultKey:type); zeroBased = (onDateObj?true:!!(typeof arguments[2]!=="undefined"? arguments[2]:true)); index = ((index - (zeroBased ? 0 : 1)) % 12); index=index<0?12+index:index; return _dateDict.month[type][index]; }; var _testDateFormat=function(day,month,year){ return day<=_maxNumberofDays(month,year); }; var date=function() { return new XaDate([].slice.call(arguments)); }; date.isValidDateString=function (str) { var dateObj={ valid:false, format:[] }, matchRes=str.match(_dateRegExp), p1,p3,p2,p1Year,p3Year,possibleFormats=[]; if(matchRes){ p1=parseInt(matchRes[1]); //dateObj.month=parseInt(matchRes[2]); p2=parseInt(matchRes[2]); p3=parseInt(matchRes[3]); //we assume hours and minutes is (mostly) defined //seconds and milliseconds is not (always) defined dateObj.hours=parseInt(matchRes[4]||0); //fastest comparison if matchRes[4] is defined dateObj.minutes=parseInt(matchRes[5]||0); //fastest comparison if matchRes[5] is defined dateObj.seconds=(matchRes[6]?parseInt(matchRes[6]):0);//faster comparison for undefined in stead of "or" dateObj.milliSeconds=(matchRes[7]?parseInt(matchRes[7]):0); //faster comparison for undefined in stead of "or" dateObj.valid=true; dateObj.multipleFormats=false; var numberToYear=function(y){ return (y<100?(y>50?1900+y:2000+y):y) }; p1Year=numberToYear(p1); p3Year=numberToYear(p3); possibleFormats=[ { day:p1,month:p2,year:p3Year,format:"DMY"}, { day:p3,month:p2,year:p1Year,format:"YMD"}, { day:p2,month:p1,year:p3Year,format:"MDY"}, { day:p2,month:p3,year:p1Year,format:"YDM"} ].filter(function(x){return (x.day<32&&x.month<13&&_testDateFormat(x.day,x.month,x.year));}); if(!possibleFormats.length){ return false; } else { dateObj.day=[]; dateObj.month=[]; dateObj.year=[]; dateObj.multipleFormats=true; dateObj.format=[]; possibleFormats.forEach(function(x){ dateObj.day.push(x.day); dateObj.month.push(x.month); dateObj.year.push(x.year); dateObj.format.push(x.format); }); return dateObj; } } else{ return false; } }; date.stringToDate = function (str,format) { var dateObj=date.isValidDateString(str); if(dateObj){ //rewrite format to index of assigned format if(typeof format!=="string"){ format=0; } else { format=dateObj.format.indexOf(format.toUpperCase()); if(format===-1){ return false; } } return date(dateObj.year[format],dateObj.month[format]-1,dateObj.day[format],dateObj.hours,dateObj.minutes,dateObj.seconds,dateObj.milliSeconds); } else{ return false; } }; function XaDate(inputArray) { var x = new(Function.prototype.bind.apply( Date, [Date].concat(inputArray))); Object.setPrototypeOf(x, XaDate.prototype); return x; } //Object.setPrototypeOf(XaDate, XaDate.prototype); Object.setPrototypeOf(XaDate.prototype, Date.prototype); XaDate.prototype.isValid = function () { return _validDate(this); }; /*if date is not set:4arguments: index of weekday,type,startindexOfWeek and zeroBased else index=date.getDay();*/ /*TODO adapt arguments optional, ...*/ date.getWeekDay=_getWeekDay.bind(null); date.month =_getMonth.bind(null); XaDate.prototype.getWeekDay =_getWeekDay; XaDate.prototype.month =_getMonth; XaDate.prototype.isLeapYear =function(){ return (this.isValid()?_leapYear(this.getFullYear()):undefined); }; date.isLeapYear = _leapYear; XaDate.prototype.daysInMonth =function(){ return (this.isValid()?_maxNumberofDays(this.getMonth()+1,this.getFullYear()):undefined); }; date.daysInMonth = _maxNumberofDays; XaDate.prototype._addSmall=function(dur){ this.addDays(dur.removeIntervalOfType("day")); this.addHours(dur.removeIntervalOfType("hour")); this.addMinutes(dur.removeIntervalOfType("minute")); this.addSeconds(dur.removeIntervalOfType("second")); this.addMilliseconds(dur.removeIntervalOfType("millisecond")); return this; }; XaDate.prototype._addBig=function(dur){ //console.log("before: "+this.toLocaleString()) var currentDay=this.getDate(),currentMonth; var decMonth=dur.month*10%10/10; var groundMonth=dur.month-decMonth; this.addYears(dur.removeIntervalOfType("year")); this.addMonths(dur.removeIntervalOfType("month",groundMonth)); //remove rounding errors dur.month=decMonth; //we get month and set date date currentMonth=this.getMonth(); this.setDate(currentDay); if (this.getMonth() !== currentMonth){ this.setDate(0); //go back to last day of previous month; } //console.log("after: "+this.toLocaleString()+") }; XaDate.prototype.format=function(formatStr){ /* //formatStr can be //d: day without leading zero //dd: day with leading zero //ddd: short day string //dddd: long day string //ddddd:single letter day string (may be more d's) //M:month without leading zero //MM or Mm:month with leading zero //mmm: short month string //mmmm: long month string //mmmmm: single letter month (may be more m's) //y or yy: 2digit year //yyy or yyyyyy: 4digit year //h: hour without leading zero //hh:hour with leading zero (or more h's) //m: minute without leading zero //mm: minute with leading zero //s: second without leading zero //ss: second with leading zero (or more s's) //.000 or ,000: any number of zero's is for the deci,centi,milliseconds, ... //all other characters are repeated as such in the string //the difference between m for minutes or month is made by the capitalization, at least one of the m's for (a one or two letter match) should be capitalized for months //all other strings could be capitalized or not. //to escape the characters use a ^ before the matching character eg ^mmm prints mmm */ /*var matchingChars=["d","D","m","M","y","Y","h","H","s","S",".",","]; var result=""; var matchingCombos={ day:/(?:[^\\/dD]|^)([dD]+)/, month:/(?:[^\\/Mm]|^)(M[Mm]?|[Mm]{3,})/, year:/(?:[^\\/yY]|^)([yY]+)/, hour:/(?:[^\\/hH]|^)([hH]+)/, minute:/(?:[^\\/m]|^)(m{1,2})/, second:/(?:[^\\/sS]|^)([sS]+)/, millisecond:/(?:[^\\/,.]|^)([,.]0+)/ }*/ var matchResult={ month:[ function(d){return (d.getMonth()+1).toString();}, function(d){return ("0"+(d.getMonth()+1)).slice(-2);}, function(d){return d.month("short");}, function(d){return d.month("long");}, function(d){return d.month("abbreviation");} ], day:[ function(d){return (d.getDate()).toString();}, function(d){return ("0"+d.getDate()).slice(-2);}, function(d){return d.getWeekDay("short");}, function(d){return d.getWeekDay("long");}, function(d){return d.getWeekDay("abbreviation");} ], year:[ function(d){return d.getFullYear().toString().slice(-2)}, function(d){return d.getFullYear().toString();}, ], /*minute:[ function(d){return (d.getMinutes()).toString();}, function(d){return ("0"+d.getMinutes()).slice(-2);} ], hour:[ function(d){return (d.getHours()).toString();}, function(d){return ("0"+d.getHours()).slice(-2);} ], second:[ function(d){return (d.getSeconds()).toString();}, function(d){return ("0"+d.getSeconds()).slice(-2);} ],*/ time:[ function(d,fn){return (d[fn]()).toString();}, function(d,fn){return ("0"+d[fn]()).slice(-2);} ], millisecond:[ function(d,len){return d.getMilliseconds().toString().slice(0,len);} ] }; var me=this; function getFormattedString(matchType){ var firstChar=matchType[0]; var matchLength=matchType.length; if (firstChar==="M"||(firstChar==="m"&&matchLength>2)){ return matchResult.month[Math.min(matchLength,5)-1](me); } else if (firstChar==="d"||firstChar==="D"){ return matchResult.day[Math.min(matchLength,5)-1](me); } else if (firstChar==="y"||firstChar==="Y"){ return matchResult.year[(matchLength>2)+0](me); } else if (firstChar==="m"&&matchLength<3){ return matchResult.time[matchLength-1](me,"getMinutes"); } else if (firstChar==="s"||firstChar==="S"){ return matchResult.time[Math.min(matchLength,2)-1](me,"getSeconds"); } else if (firstChar==="h"||firstChar==="H"){ return matchResult.time[Math.min(matchLength,2)-1](me,"getHours"); } else if (firstChar==="."||firstChar===","){ return matchResult.millisecond[0](me,matchLength-1); } } //var reDateString=/(?:[^\\/dD]|^)[dD]+|(?:[^\\/Mm]|^)M[Mm]?|[Mm]{3,}|(?:[^\\/yY]|^)[yY]+|(?:[^\\/hH]|^)[hH]+|(?:[^\\/m]|^)m{1,2}|(?:[^\\/sS]|^)[sS]+|(?:[^\\/,.]|^)[,.]0+/g; var reDateString=/[\s\S]([dD]+|M[Mm]?|[Mm]{3,}|[yY]+|[hH]+|m{1,2}|[sS]+|[,.]0+)/g; return ("1"+formatStr).replace(reDateString,function(m){ var firstChar=m[0],match=m.slice(1); if(firstChar==="^"){ return match; } else{ return firstChar+getFormattedString(match); } }).slice(1) }; XaDate.prototype.until=function(otherDate){ if(!_validDate(otherDate)){ //try to create other date object otherDate=new XaDate([].slice.call(arguments)); } if(!otherDate.isValid()){ throw new TypeError('until() needs a date or parseable dateargumenrs'); } return duration(otherDate.valueOf()-this.valueOf()); }; XaDate.prototype.add=function(dur/*,firstBig*/){ //console.log(dur); var args=[].slice.call(arguments); var firstBig=args.pop(); if(typeof firstBig!=="boolean"){ args.push(firstBig); firstBig=true; //this makes a difference in subtracting durations } //console.log(dur); if(dur.constructor.name!=="XaDuration"){ dur=duration.apply(null,args); } dur.normalizeDown(); if (firstBig){ this._addBig(dur); dur.normalizeMonth(this.daysInMonth()); } //console.log(dur) this._addSmall(dur); if(!firstBig){ dur.normalizeMonth(this.daysInMonth()); this._addSmall(dur); this._addBig(dur); } return this; }; XaDate.prototype.addMonths=function(m){ //faster implementation than datejs var day,month; if(typeof m!=="number"){ return this; } day=this.getDate(); this.setMonth(this.getMonth() + m, 1); month=this.getMonth(); this.setDate(day); if (this.getMonth() !== month){ this.setDate(0); //go back to last day of previous month; } return this; }; XaDate.prototype.addYears=function(y){ //faster implementation than datejs var month; if(typeof y!=="number"){ return this; } month=this.getMonth(); //day=this.getDate() this.setFullYear(this.getFullYear() + y,month); if (this.getMonth() !== month){ this.setDate(0); //go back to last day of previous month; } return this; }; XaDate.prototype.addDays=function(d){ if(typeof d!=="number"){ return this; } this.setDate(this.getDate()+d); return this; }; XaDate.prototype.addHours=function(h){ if(typeof h!=="number"){ return this; } this.setHours(this.getHours()+h); return this; }; XaDate.prototype.addMinutes=function(m){ if(typeof m!=="number"){ return this; } this.setMinutes(this.getMinutes()+m); return this; }; XaDate.prototype.addSeconds=function(s){ if(typeof s!=="number"){ return this; } this.setSeconds(this.getSeconds()+s); return this; }; XaDate.prototype.addMilliseconds=function(m){ if(typeof m!=="number"){ return this; } this.setMilliseconds(this.getMilliseconds()+m); return this; }; exports.date = date; Object.defineProperty(exports, '__esModule', { value: true }); })));