Last active
December 17, 2015 05:59
-
-
Save puppybits/5561723 to your computer and use it in GitHub Desktop.
Create a date that iterates on either multiple dates of the month or every X number of days
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
// EXAMPLES: | |
var payday = new SeriesDate('DAILY', [14], '1/15/2010') | |
var gas = new SeriesDate('MONTHLY', [1,15], '1/15/2010') | |
var electricity = new SeriesDate('MONTHLY', [20], '1/15/2010') | |
payday.next(); // move to next payday | |
payday.prev(); // move to previous payday | |
// TODO: fix bad hack to subclass Date (http://www.2ality.com/2013/03/subclassing-builtins-es6.html) | |
// only tested in chrome | |
*/ | |
function SeriesDate( seriesType, series, start ) | |
{ | |
var _this = new Date(start); | |
_this.__proto__ = SeriesDate.prototype; | |
for(var i in series){ if (series[i]>28)series[i]=28} | |
var _seriesType = seriesType, | |
_series = series.sort(), | |
_start = new Date(start.toString()), | |
setLastDate = function(d) | |
{ | |
nextMonth(d); | |
d.setDate(0); /* set date 0 will subtract one day */ | |
}, | |
nextMonth = function(d) | |
{ | |
if (d.getMonth() < 11) | |
{ | |
d.setMonth( (d.getMonth()+1) ); | |
} | |
else | |
{ | |
d.setMonth(0); | |
d.setFullYear(d.getFullYear()+1); | |
} | |
return d; | |
}, | |
nextDate = function(d, date) | |
{ | |
if (d.getDate() < date) | |
{ | |
(date < 28) ? d.setDate(date) : setLastDate(d); | |
} | |
else | |
{ | |
if (date < 28) | |
{ | |
d.setDate(1) | |
nextMonth(d); | |
d.setDate(date); | |
} | |
else | |
{ | |
setLastDate(d); | |
} | |
} | |
return d; | |
}, | |
previousMonth = function(d) | |
{ | |
if (d.getMonth() > 0) | |
{ | |
d.setMonth(d.getMonth()-1); | |
} | |
else | |
{ | |
d.setMonth(11); | |
d.setFullYear(d.getFullYear()-1); | |
} | |
return d; | |
}, | |
previousDate = function(d, date) | |
{ | |
if (d.getDate() > date) | |
{ | |
(date < 28) ? d.setDate(date) : d.setDate(0); | |
} | |
else | |
{ | |
if (date < 28) | |
{ | |
previousMonth(d); | |
d.setDate(date); | |
} | |
else | |
{ | |
d.setDate(1); | |
previousMonth(d); | |
setLastDate(d); | |
} | |
} | |
return d; | |
}, | |
nextMonthlyDate = function(date, monthSeries, start) | |
{ | |
var isBeforeStartDate = (start.getTime() > date.getTime()), | |
d = [date.getFullYear(), date.getMonth(), date.getDate()]; | |
if (isBeforeStartDate) | |
return new Date(start.toString()); | |
for (var i in monthSeries) | |
{ | |
if (monthSeries[i] > d[2]) | |
return nextDate(date, monthSeries[i]) | |
} | |
return nextDate(date, monthSeries[0]) | |
}, | |
previousMonthlyDate = function(date, monthSeries, start) | |
{ | |
var isBeforeStartDate = (start.getTime() > date.getTime()), | |
d = [date.getFullYear(), date.getMonth(), Math.min(date.getDate(), 28)]; | |
if (isBeforeStartDate) | |
return new Date(start.toString()); | |
for (var i=monthSeries.length-1; i>=0; i--) | |
{ | |
if (monthSeries[i] < d[2]) | |
return previousDate(date, monthSeries[i]) | |
} | |
return previousDate(date, monthSeries[monthSeries.length-1]) | |
}, | |
nextDailyDate = function(date, day, start) | |
{ | |
var isBeforeStartDate = (start.getTime() > date.getTime()); | |
if (isBeforeStartDate) | |
return new Date(start.toString()); | |
day *= 86400000; | |
date.setTime(date.getTime() + day) | |
return date; | |
}, | |
previousDailyDate = function(date, day, start) | |
{ | |
var isBeforeStartDate = (start.getTime() > date.getTime()); | |
if (isBeforeStartDate) | |
return new Date(start.toString()); | |
day *= 86400000; | |
date.setTime(date.getTime() - day) | |
return date; | |
}; | |
if (seriesType ==='MONTHLY') | |
{ | |
_this.next = function(){ | |
return nextMonthlyDate(this, _series, _start); | |
}; | |
_this.prev = function(){ | |
return previousMonthlyDate(this, _series, _start); | |
}; | |
} | |
else | |
{ | |
_this.next = function(){ | |
return nextDailyDate(this, _series, _start); | |
}; | |
_this.prev = function(){ | |
return previousDailyDate(this, _series, _start); | |
}; | |
} | |
/* move to first future date */ | |
var now = new Date().getTime(); | |
while (now > _this.getTime() ) | |
{ | |
_this.next() | |
} | |
return _this; | |
} | |
SeriesDate.prototype = Object.create(Date.prototype); | |
// TODO: upload unit tests |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment