12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910 |
- (function(root){
- var serverSide = typeof module !== 'undefined' && module.exports;
- var getnlp = function() {
- if (!getnlp._nlp) {
- if (serverSide) {
-
- getnlp._nlp = require('./nlp')
- } else if (!(getnlp._nlp = root._RRuleNLP)) {
- throw new Error(
- 'You need to include rrule/nlp.js for fromText/toText to work.'
- )
- }
- }
- return getnlp._nlp;
- };
- var dateutil = {
- MONTH_DAYS: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
-
- ONE_DAY: 1000 * 60 * 60 * 24,
-
- MAXYEAR: 9999,
-
- ORDINAL_BASE: new Date(1970, 0, 1),
-
- PY_WEEKDAYS: [6, 0, 1, 2, 3, 4, 5],
-
- getYearDay: function(date) {
- var dateNoTime = new Date(
- date.getFullYear(), date.getMonth(), date.getDate());
- return Math.ceil(
- (dateNoTime - new Date(date.getFullYear(), 0, 1))
- / dateutil.ONE_DAY) + 1;
- },
- isLeapYear: function(year) {
- if (year instanceof Date) {
- year = year.getFullYear();
- }
- return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0);
- },
-
- tzOffset: function(date) {
- return date.getTimezoneOffset() * 60 * 1000
- },
-
- daysBetween: function(date1, date2) {
-
-
- var date1_ms = date1.getTime() - dateutil.tzOffset(date1);
- var date2_ms = date2.getTime() - dateutil.tzOffset(date2);
-
- var difference_ms = Math.abs(date1_ms - date2_ms);
-
- return Math.round(difference_ms / dateutil.ONE_DAY);
- },
-
- toOrdinal: function(date) {
- return dateutil.daysBetween(date, dateutil.ORDINAL_BASE);
- },
-
- fromOrdinal: function(ordinal) {
- var millisecsFromBase = ordinal * dateutil.ONE_DAY;
- return new Date(dateutil.ORDINAL_BASE.getTime()
- - dateutil.tzOffset(dateutil.ORDINAL_BASE)
- + millisecsFromBase
- + dateutil.tzOffset(new Date(millisecsFromBase)));
- },
-
- monthRange: function(year, month) {
- var date = new Date(year, month, 1);
- return [dateutil.getWeekday(date), dateutil.getMonthDays(date)];
- },
- getMonthDays: function(date) {
- var month = date.getMonth();
- return month == 1 && dateutil.isLeapYear(date)
- ? 29
- : dateutil.MONTH_DAYS[month];
- },
-
- getWeekday: function(date) {
- return dateutil.PY_WEEKDAYS[date.getDay()];
- },
-
- combine: function(date, time) {
- time = time || date;
- return new Date(
- date.getFullYear(), date.getMonth(), date.getDate(),
- time.getHours(), time.getMinutes(), time.getSeconds()
- );
- },
- clone: function(date) {
- var dolly = new Date(date.getTime());
- dolly.setMilliseconds(0);
- return dolly;
- },
- cloneDates: function(dates) {
- var clones = [];
- for (var i = 0; i < dates.length; i++) {
- clones.push(dateutil.clone(dates[i]));
- }
- return clones;
- },
-
- sort: function(dates) {
- dates.sort(function(a, b){
- return a.getTime() - b.getTime();
- });
- },
- timeToUntilString: function(time) {
- var date = new Date(time);
- var comp, comps = [
- date.getUTCFullYear(),
- date.getUTCMonth() + 1,
- date.getUTCDate(),
- 'T',
- date.getUTCHours(),
- date.getUTCMinutes(),
- date.getUTCSeconds(),
- 'Z'
- ];
- for (var i = 0; i < comps.length; i++) {
- comp = comps[i];
- if (!/[TZ]/.test(comp) && comp < 10) {
- comps[i] = '0' + String(comp);
- }
- }
- return comps.join('');
- },
- untilStringToDate: function(until) {
- var re = /^(\d{4})(\d{2})(\d{2})(T(\d{2})(\d{2})(\d{2})Z)?$/;
- var bits = re.exec(until);
- if (!bits) {
- throw new Error('Invalid UNTIL value: ' + until)
- }
- return new Date(
- Date.UTC(bits[1],
- bits[2] - 1,
- bits[3],
- bits[5] || 0,
- bits[6] || 0,
- bits[7] || 0
- ));
- }
- };
- dateutil.Time = function(hour, minute, second) {
- this.hour = hour;
- this.minute = minute;
- this.second = second;
- };
- dateutil.Time.prototype = {
- getHours: function() {
- return this.hour;
- },
- getMinutes: function() {
- return this.minute;
- },
- getSeconds: function() {
- return this.second;
- },
- getTime: function() {
- return ((this.hour * 60 * 60)
- + (this.minute * 60)
- + this.second)
- * 1000;
- }
- };
- var range = function(start, end) {
- if (arguments.length === 1) {
- end = start;
- start = 0;
- }
- var rang = [];
- for (var i = start; i < end; i++) {
- rang.push(i);
- }
- return rang;
- };
- var repeat = function(value, times) {
- var i = 0, array = [];
- if (value instanceof Array) {
- for (; i < times; i++) {
- array[i] = [].concat(value);
- }
- } else {
- for (; i < times; i++) {
- array[i] = value;
- }
- }
- return array;
- };
- var pymod = function(a, b) {
- var r = a % b;
-
- return (r * b < 0) ? r + b : r;
- };
- var divmod = function(a, b) {
- return {div: Math.floor(a / b), mod: pymod(a, b)};
- };
- var plb = function(obj) {
- return (obj instanceof Array && obj.length == 0)
- ? false
- : Boolean(obj);
- };
- var contains = function(arr, val) {
- return arr.indexOf(val) != -1;
- };
- var M365MASK = [].concat(
- repeat(1, 31), repeat(2, 28), repeat(3, 31),
- repeat(4, 30), repeat(5, 31), repeat(6, 30),
- repeat(7, 31), repeat(8, 31), repeat(9, 30),
- repeat(10, 31), repeat(11, 30), repeat(12, 31),
- repeat(1, 7)
- );
- var M366MASK = [].concat(
- repeat(1, 31), repeat(2, 29), repeat(3, 31),
- repeat(4, 30), repeat(5, 31), repeat(6, 30),
- repeat(7, 31), repeat(8, 31), repeat(9, 30),
- repeat(10, 31), repeat(11, 30), repeat(12, 31),
- repeat(1, 7)
- );
- var
- M28 = range(1, 29),
- M29 = range(1, 30),
- M30 = range(1, 31),
- M31 = range(1, 32);
- var MDAY366MASK = [].concat(
- M31, M29, M31,
- M30, M31, M30,
- M31, M31, M30,
- M31, M30, M31,
- M31.slice(0, 7)
- );
- var MDAY365MASK = [].concat(
- M31, M28, M31,
- M30, M31, M30,
- M31, M31, M30,
- M31, M30, M31,
- M31.slice(0, 7)
- );
- M28 = range(-28, 0);
- M29 = range(-29, 0);
- M30 = range(-30, 0);
- M31 = range(-31, 0);
- var NMDAY366MASK = [].concat(
- M31, M29, M31,
- M30, M31, M30,
- M31, M31, M30,
- M31, M30, M31,
- M31.slice(0, 7)
- );
- var NMDAY365MASK = [].concat(
- M31, M28, M31,
- M30, M31, M30,
- M31, M31, M30,
- M31, M30, M31,
- M31.slice(0, 7)
- );
- var M366RANGE = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366];
- var M365RANGE = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
- var WDAYMASK = (function() {
- for (var wdaymask = [], i = 0; i < 55; i++) {
- wdaymask = wdaymask.concat(range(7));
- }
- return wdaymask;
- }());
- var Weekday = function(weekday, n) {
- if (n === 0) {
- throw new Error('Can\'t create weekday with n == 0');
- }
- this.weekday = weekday;
- this.n = n;
- };
- Weekday.prototype = {
-
-
- nth: function(n) {
- return this.n == n ? this : new Weekday(this.weekday, n);
- },
-
- equals: function(other) {
- return this.weekday == other.weekday && this.n == other.n;
- },
-
- toString: function() {
- var s = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'][this.weekday];
- if (this.n) {
- s = (this.n > 0 ? '+' : '') + String(this.n) + s;
- }
- return s;
- },
- getJsWeekday: function() {
- return this.weekday == 6 ? 0 : this.weekday + 1;
- }
- };
- var RRule = function(options, noCache) {
-
- this._string = null;
- options = options || {};
- this._cache = noCache ? null : {
- all: false,
- before: [],
- after: [],
- between: []
- };
-
- this.origOptions = {};
- var invalid = [],
- keys = Object.keys(options),
- defaultKeys = Object.keys(RRule.DEFAULT_OPTIONS);
-
- keys.forEach(function(key) {
- this.origOptions[key] = options[key];
- if (!contains(defaultKeys, key)) invalid.push(key);
- }, this);
- if (invalid.length) {
- throw new Error('Invalid options: ' + invalid.join(', '))
- }
- if (!RRule.FREQUENCIES[options.freq] && options.byeaster === null) {
- throw new Error('Invalid frequency: ' + String(options.freq))
- }
-
- defaultKeys.forEach(function(key) {
- if (!contains(keys, key)) options[key] = RRule.DEFAULT_OPTIONS[key];
- });
- var opts = this.options = options;
- if (opts.byeaster !== null) {
- opts.freq = RRule.YEARLY;
- }
- if (!opts.dtstart) {
- opts.dtstart = new Date();
- opts.dtstart.setMilliseconds(0);
- }
- if (opts.wkst === null) {
- opts.wkst = RRule.MO.weekday;
- } else if (typeof opts.wkst == 'number') {
-
- } else {
- opts.wkst = opts.wkst.weekday;
- }
- if (opts.bysetpos !== null) {
- if (typeof opts.bysetpos == 'number') {
- opts.bysetpos = [opts.bysetpos];
- }
- for (var i = 0; i < opts.bysetpos.length; i++) {
- var v = opts.bysetpos[i];
- if (v == 0 || !(-366 <= v && v <= 366)) {
- throw new Error(
- 'bysetpos must be between 1 and 366,' +
- ' or between -366 and -1'
- );
- }
- }
- }
- if (!(plb(opts.byweekno) || plb(opts.byyearday)
- || plb(opts.bymonthday) || opts.byweekday !== null
- || opts.byeaster !== null))
- {
- switch (opts.freq) {
- case RRule.YEARLY:
- if (!opts.bymonth) {
- opts.bymonth = opts.dtstart.getMonth() + 1;
- }
- opts.bymonthday = opts.dtstart.getDate();
- break;
- case RRule.MONTHLY:
- opts.bymonthday = opts.dtstart.getDate();
- break;
- case RRule.WEEKLY:
- opts.byweekday = dateutil.getWeekday(
- opts.dtstart);
- break;
- }
- }
-
- if (opts.bymonth !== null
- && !(opts.bymonth instanceof Array)) {
- opts.bymonth = [opts.bymonth];
- }
-
- if (opts.byyearday !== null
- && !(opts.byyearday instanceof Array)) {
- opts.byyearday = [opts.byyearday];
- }
-
- if (opts.bymonthday === null) {
- opts.bymonthday = [];
- opts.bynmonthday = [];
- } else if (opts.bymonthday instanceof Array) {
- var bymonthday = [], bynmonthday = [];
- for (i = 0; i < opts.bymonthday.length; i++) {
- var v = opts.bymonthday[i];
- if (v > 0) {
- bymonthday.push(v);
- } else if (v < 0) {
- bynmonthday.push(v);
- }
- }
- opts.bymonthday = bymonthday;
- opts.bynmonthday = bynmonthday;
- } else {
- if (opts.bymonthday < 0) {
- opts.bynmonthday = [opts.bymonthday];
- opts.bymonthday = [];
- } else {
- opts.bynmonthday = [];
- opts.bymonthday = [opts.bymonthday];
- }
- }
-
- if (opts.byweekno !== null
- && !(opts.byweekno instanceof Array)) {
- opts.byweekno = [opts.byweekno];
- }
-
- if (opts.byweekday === null) {
- opts.bynweekday = null;
- } else if (typeof opts.byweekday == 'number') {
- opts.byweekday = [opts.byweekday];
- opts.bynweekday = null;
- } else if (opts.byweekday instanceof Weekday) {
- if (!opts.byweekday.n || opts.freq > RRule.MONTHLY) {
- opts.byweekday = [opts.byweekday.weekday];
- opts.bynweekday = null;
- } else {
- opts.bynweekday = [
- [opts.byweekday.weekday,
- opts.byweekday.n]
- ];
- opts.byweekday = null;
- }
- } else {
- var byweekday = [], bynweekday = [];
- for (i = 0; i < opts.byweekday.length; i++) {
- var wday = opts.byweekday[i];
- if (typeof wday == 'number') {
- byweekday.push(wday);
- } else if (!wday.n || opts.freq > RRule.MONTHLY) {
- byweekday.push(wday.weekday);
- } else {
- bynweekday.push([wday.weekday, wday.n]);
- }
- }
- opts.byweekday = plb(byweekday) ? byweekday : null;
- opts.bynweekday = plb(bynweekday) ? bynweekday : null;
- }
-
- if (opts.byhour === null) {
- opts.byhour = (opts.freq < RRule.HOURLY)
- ? [opts.dtstart.getHours()]
- : null;
- } else if (typeof opts.byhour == 'number') {
- opts.byhour = [opts.byhour];
- }
-
- if (opts.byminute === null) {
- opts.byminute = (opts.freq < RRule.MINUTELY)
- ? [opts.dtstart.getMinutes()]
- : null;
- } else if (typeof opts.byminute == 'number') {
- opts.byminute = [opts.byminute];
- }
-
- if (opts.bysecond === null) {
- opts.bysecond = (opts.freq < RRule.SECONDLY)
- ? [opts.dtstart.getSeconds()]
- : null;
- } else if (typeof opts.bysecond == 'number') {
- opts.bysecond = [opts.bysecond];
- }
- if (opts.freq >= RRule.HOURLY) {
- this.timeset = null;
- } else {
- this.timeset = [];
- for (i = 0; i < opts.byhour.length; i++) {
- var hour = opts.byhour[i];
- for (var j = 0; j < opts.byminute.length; j++) {
- var minute = opts.byminute[j];
- for (var k = 0; k < opts.bysecond.length; k++) {
- var second = opts.bysecond[k];
-
-
-
- this.timeset.push(new dateutil.Time(hour, minute, second));
- }
- }
- }
- dateutil.sort(this.timeset);
- }
- };
- RRule.FREQUENCIES = [
- 'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY',
- 'HOURLY', 'MINUTELY', 'SECONDLY'
- ];
- RRule.YEARLY = 0;
- RRule.MONTHLY = 1;
- RRule.WEEKLY = 2;
- RRule.DAILY = 3;
- RRule.HOURLY = 4;
- RRule.MINUTELY = 5;
- RRule.SECONDLY = 6;
- RRule.MO = new Weekday(0);
- RRule.TU = new Weekday(1);
- RRule.WE = new Weekday(2);
- RRule.TH = new Weekday(3);
- RRule.FR = new Weekday(4);
- RRule.SA = new Weekday(5);
- RRule.SU = new Weekday(6);
- RRule.DEFAULT_OPTIONS = {
- freq: null,
- dtstart: null,
- interval: 1,
- wkst: RRule.MO,
- count: null,
- until: null,
- bysetpos: null,
- bymonth: null,
- bymonthday: null,
- byyearday: null,
- byweekno: null,
- byweekday: null,
- byhour: null,
- byminute: null,
- bysecond: null,
- byeaster: null
- };
- RRule.parseText = function(text, language) {
- return getnlp().parseText(text, language)
- };
- RRule.fromText = function(text, language) {
- return getnlp().fromText(text, language)
- };
- RRule.optionsToString = function(options) {
- var key, keys, defaultKeys, value, strValues, pairs = [];
- keys = Object.keys(options);
- defaultKeys = Object.keys(RRule.DEFAULT_OPTIONS);
- for (var i = 0; i < keys.length; i++) {
- if (!contains(defaultKeys, keys[i])) continue;
- key = keys[i].toUpperCase();
- value = options[keys[i]];
- strValues = [];
- if (value === null || value instanceof Array && !value.length) {
- continue;
- }
- switch (key) {
- case 'FREQ':
- value = RRule.FREQUENCIES[options.freq];
- break;
- case 'WKST':
- value = value.toString();
- break;
- case 'BYWEEKDAY':
-
- key = 'BYDAY';
- if (!(value instanceof Array)) {
- value = [value];
- }
- for (var wday, j = 0; j < value.length; j++) {
- wday = value[j];
- if (wday instanceof Weekday) {
-
- } else if (wday instanceof Array) {
- wday = new Weekday(wday[0], wday[1]);
- } else {
- wday = new Weekday(wday);
- }
- strValues[j] = wday.toString();
- }
- value = strValues;
- break;
- case'DTSTART':
- case'UNTIL':
- value = dateutil.timeToUntilString(value);
- break;
- default:
- if (value instanceof Array) {
- for (var j = 0; j < value.length; j++) {
- strValues[j] = String(value[j]);
- }
- value = strValues;
- } else {
- value = String(value);
- }
- }
- pairs.push([key, value]);
- }
- var strings = [];
- for (var i = 0; i < pairs.length; i++) {
- var attr = pairs[i];
- strings.push(attr[0] + '=' + attr[1].toString());
- }
- return strings.join(';');
- };
- RRule.prototype = {
-
- all: function(iterator) {
- if (iterator) {
- return this._iter(new CallbackIterResult('all', {}, iterator));
- } else {
- var result = this._cacheGet('all');
- if (result === false) {
- result = this._iter(new IterResult('all', {}));
- this._cacheAdd('all', result);
- }
- return result;
- }
- },
-
- between: function(after, before, inc, iterator) {
- var args = {
- before: before,
- after: after,
- inc: inc
- }
- if (iterator) {
- return this._iter(
- new CallbackIterResult('between', args, iterator));
- } else {
- var result = this._cacheGet('between', args);
- if (result === false) {
- result = this._iter(new IterResult('between', args));
- this._cacheAdd('between', result, args);
- }
- return result;
- }
- },
-
- before: function(dt, inc) {
- var args = {
- dt: dt,
- inc: inc
- },
- result = this._cacheGet('before', args);
- if (result === false) {
- result = this._iter(new IterResult('before', args));
- this._cacheAdd('before', result, args);
- }
- return result;
- },
-
- after: function(dt, inc) {
- var args = {
- dt: dt,
- inc: inc
- },
- result = this._cacheGet('after', args);
- if (result === false) {
- result = this._iter(new IterResult('after', args));
- this._cacheAdd('after', result, args);
- }
- return result;
- },
-
- count: function() {
- return this.all().length;
- },
-
- toString: function() {
- return RRule.optionsToString(this.origOptions);
- },
-
- toText: function(gettext, language) {
- return getnlp().toText(this, gettext, language);
- },
- isFullyConvertibleToText: function() {
- return getnlp().isFullyConvertible(this)
- },
-
- _cacheAdd: function(what, value, args) {
- if (!this._cache) return;
- if (value) {
- value = (value instanceof Date)
- ? dateutil.clone(value)
- : dateutil.cloneDates(value);
- }
- if (what == 'all') {
- this._cache.all = value;
- } else {
- args._value = value;
- this._cache[what].push(args);
- }
- },
-
- _cacheGet: function(what, args) {
- if (!this._cache) {
- return false;
- }
- var cached = false;
- if (what == 'all') {
- cached = this._cache.all;
- } else {
-
-
- loopItems:
- for (var item, i = 0; i < this._cache[what].length; i++) {
- item = this._cache[what][i];
- for (var k in args) {
- if (args.hasOwnProperty(k)
- && String(args[k]) != String(item[k])) {
- continue loopItems;
- }
- }
- cached = item._value;
- break;
- }
- }
- if (!cached && this._cache.all) {
-
-
- var iterResult = new IterResult(what, args);
- for (var i = 0; i < this._cache.all.length; i++) {
- if (!iterResult.accept(this._cache.all[i])) {
- break;
- }
- }
- cached = iterResult.getValue();
- this._cacheAdd(what, cached, args);
- }
- return cached instanceof Array
- ? dateutil.cloneDates(cached)
- : (cached instanceof Date
- ? dateutil.clone(cached)
- : cached);
- },
-
- clone: function() {
- return new RRule(this.origOptions);
- },
- _iter: function(iterResult) {
-
- var dtstart = this.options.dtstart;
- var
- year = dtstart.getFullYear(),
- month = dtstart.getMonth() + 1,
- day = dtstart.getDate(),
- hour = dtstart.getHours(),
- minute = dtstart.getMinutes(),
- second = dtstart.getSeconds(),
- weekday = dateutil.getWeekday(dtstart),
- yearday = dateutil.getYearDay(dtstart);
-
- var
- freq = this.options.freq,
- interval = this.options.interval,
- wkst = this.options.wkst,
- until = this.options.until,
- bymonth = this.options.bymonth,
- byweekno = this.options.byweekno,
- byyearday = this.options.byyearday,
- byweekday = this.options.byweekday,
- byeaster = this.options.byeaster,
- bymonthday = this.options.bymonthday,
- bynmonthday = this.options.bynmonthday,
- bysetpos = this.options.bysetpos,
- byhour = this.options.byhour,
- byminute = this.options.byminute,
- bysecond = this.options.bysecond;
- var ii = new Iterinfo(this);
- ii.rebuild(year, month);
- var getdayset = {};
- getdayset[RRule.YEARLY] = ii.ydayset;
- getdayset[RRule.MONTHLY] = ii.mdayset;
- getdayset[RRule.WEEKLY] = ii.wdayset;
- getdayset[RRule.DAILY] = ii.ddayset;
- getdayset[RRule.HOURLY] = ii.ddayset;
- getdayset[RRule.MINUTELY] = ii.ddayset;
- getdayset[RRule.SECONDLY] = ii.ddayset;
- getdayset = getdayset[freq];
- var timeset;
- if (freq < RRule.HOURLY) {
- timeset = this.timeset;
- } else {
- var gettimeset = {};
- gettimeset[RRule.HOURLY] = ii.htimeset;
- gettimeset[RRule.MINUTELY] = ii.mtimeset;
- gettimeset[RRule.SECONDLY] = ii.stimeset;
- gettimeset = gettimeset[freq];
- if ((freq >= RRule.HOURLY && plb(byhour) && !contains(byhour, hour)) ||
- (freq >= RRule.MINUTELY && plb(byminute) && !contains(byminute, minute)) ||
- (freq >= RRule.SECONDLY && plb(bysecond) && !contains(bysecond, minute)))
- {
- timeset = [];
- } else {
- timeset = gettimeset.call(ii, hour, minute, second);
- }
- }
- var filtered, total = 0, count = this.options.count;
- var iterNo = 0;
- var i, j, k, dm, div, mod, tmp, pos, dayset, start, end, fixday;
- while (true) {
-
- tmp = getdayset.call(ii, year, month, day);
- dayset = tmp[0]; start = tmp[1]; end = tmp[2];
-
- filtered = false;
- for (j = start; j < end; j++) {
- i = dayset[j];
- if ((plb(bymonth) && !contains(bymonth, ii.mmask[i])) ||
- (plb(byweekno) && !ii.wnomask[i]) ||
- (plb(byweekday) && !contains(byweekday, ii.wdaymask[i])) ||
- (plb(ii.nwdaymask) && !ii.nwdaymask[i]) ||
- (byeaster !== null && !contains(ii.eastermask, i)) ||
- (
- (plb(bymonthday) || plb(bynmonthday)) &&
- !contains(bymonthday, ii.mdaymask[i]) &&
- !contains(bynmonthday, ii.nmdaymask[i])
- )
- ||
- (
- plb(byyearday)
- &&
- (
- (
- i < ii.yearlen &&
- !contains(byyearday, i + 1) &&
- !contains(byyearday, -ii.yearlen + i)
- )
- ||
- (
- i >= ii.yearlen &&
- !contains(byyearday, i + 1 - ii.yearlen) &&
- !contains(byyearday, -ii.nextyearlen + i - ii.yearlen)
- )
- )
- )
- )
- {
- dayset[i] = null;
- filtered = true;
- }
- }
-
- if (plb(bysetpos) && plb(timeset)) {
- var daypos, timepos, poslist = [];
- for (i, j = 0; j < bysetpos.length; j++) {
- var pos = bysetpos[j];
- if (pos < 0) {
- daypos = Math.floor(pos / timeset.length);
- timepos = pymod(pos, timeset.length);
- } else {
- daypos = Math.floor((pos - 1) / timeset.length);
- timepos = pymod((pos - 1), timeset.length);
- }
- try {
- tmp = [];
- for (k = start; k < end; k++) {
- var val = dayset[k];
- if (val === null) {
- continue;
- }
- tmp.push(val);
- }
- if (daypos < 0) {
-
- i = tmp.slice(daypos)[0];
- } else {
- i = tmp[daypos];
- }
- var time = timeset[timepos];
- var date = dateutil.fromOrdinal(ii.yearordinal + i);
- var res = dateutil.combine(date, time);
-
-
- if (!contains(poslist, res)) {
- poslist.push(res);
- }
- } catch (e) {}
- }
- dateutil.sort(poslist);
- for (j = 0; j < poslist.length; j++) {
- var res = poslist[j];
- if (until && res > until) {
- this._len = total;
- return iterResult.getValue();
- } else if (res >= dtstart) {
- ++total;
- if (!iterResult.accept(res)) {
- return iterResult.getValue();
- }
- if (count) {
- --count;
- if (!count) {
- this._len = total;
- return iterResult.getValue();
- }
- }
- }
- }
- } else {
- for (j = start; j < end; j++) {
- i = dayset[j];
- if (i !== null) {
- var date = dateutil.fromOrdinal(ii.yearordinal + i);
- for (k = 0; k < timeset.length; k++) {
- var time = timeset[k];
- var res = dateutil.combine(date, time);
- if (until && res > until) {
- this._len = total;
- return iterResult.getValue();
- } else if (res >= dtstart) {
- ++total;
- if (!iterResult.accept(res)) {
- return iterResult.getValue();
- }
- if (count) {
- --count;
- if (!count) {
- this._len = total;
- return iterResult.getValue();
- }
- }
- }
- }
- }
- }
- }
-
- fixday = false;
- if (freq == RRule.YEARLY) {
- year += interval;
- if (year > dateutil.MAXYEAR) {
- this._len = total;
- return iterResult.getValue();
- }
- ii.rebuild(year, month);
- } else if (freq == RRule.MONTHLY) {
- month += interval;
- if (month > 12) {
- div = Math.floor(month / 12);
- mod = pymod(month, 12);
- month = mod;
- year += div;
- if (month == 0) {
- month = 12;
- --year;
- }
- if (year > dateutil.MAXYEAR) {
- this._len = total;
- return iterResult.getValue();
- }
- }
- ii.rebuild(year, month);
- } else if (freq == RRule.WEEKLY) {
- if (wkst > weekday) {
- day += -(weekday + 1 + (6 - wkst)) + interval * 7;
- } else {
- day += -(weekday - wkst) + interval * 7;
- }
- weekday = wkst;
- fixday = true;
- } else if (freq == RRule.DAILY) {
- day += interval;
- fixday = true;
- } else if (freq == RRule.HOURLY) {
- if (filtered) {
-
- hour += Math.floor((23 - hour) / interval) * interval;
- }
- while (true) {
- hour += interval;
- dm = divmod(hour, 24);
- div = dm.div;
- mod = dm.mod;
- if (div) {
- hour = mod;
- day += div;
- fixday = true;
- }
- if (!plb(byhour) || contains(byhour, hour)) {
- break;
- }
- }
- timeset = gettimeset.call(ii, hour, minute, second);
- } else if (freq == RRule.MINUTELY) {
- if (filtered) {
-
- minute += Math.floor(
- (1439 - (hour * 60 + minute)) / interval) * interval;
- }
- while(true) {
- minute += interval;
- dm = divmod(minute, 60);
- div = dm.div;
- mod = dm.mod;
- if (div) {
- minute = mod;
- hour += div;
- dm = divmod(hour, 24);
- div = dm.div;
- mod = dm.mod;
- if (div) {
- hour = mod;
- day += div;
- fixday = true;
- filtered = false;
- }
- }
- if ((!plb(byhour) || contains(byhour, hour)) &&
- (!plb(byminute) || contains(byminute, minute))) {
- break;
- }
- }
- timeset = gettimeset.call(ii, hour, minute, second);
- } else if (freq == RRule.SECONDLY) {
- if (filtered) {
-
- second += Math.floor(
- (86399 - (hour * 3600 + minute * 60 + second))
- / interval) * interval;
- }
- while (true) {
- second += interval;
- dm = divmod(second, 60);
- div = dm.div;
- mod = dm.mod;
- if (div) {
- second = mod;
- minute += div;
- dm = divmod(minute, 60);
- div = dm.div;
- mod = dm.mod;
- if (div) {
- minute = mod;
- hour += div;
- dm = divmod(hour, 24);
- div = dm.div;
- mod = dm.mod;
- if (div) {
- hour = mod;
- day += div;
- fixday = true;
- }
- }
- }
- if ((!plb(byhour) || contains(byhour, hour)) &&
- (!plb(byminute) || contains(byminute, minute)) &&
- (!plb(bysecond) || contains(bysecond, second)))
- {
- break;
- }
- }
- timeset = gettimeset.call(ii, hour, minute, second);
- }
- if (fixday && day > 28) {
- var daysinmonth = dateutil.monthRange(year, month - 1)[1];
- if (day > daysinmonth) {
- while (day > daysinmonth) {
- day -= daysinmonth;
- ++month;
- if (month == 13) {
- month = 1;
- ++year;
- if (year > dateutil.MAXYEAR) {
- this._len = total;
- return iterResult.getValue();
- }
- }
- daysinmonth = dateutil.monthRange(year, month - 1)[1];
- }
- ii.rebuild(year, month);
- }
- }
- }
- }
- };
- RRule.parseString = function(rfcString) {
- rfcString = rfcString.replace(/^\s+|\s+$/, '');
- if (!rfcString.length) {
- return null;
- }
- var i, j, key, value, attr,
- attrs = rfcString.split(';'),
- options = {};
- for (i = 0; i < attrs.length; i++) {
- attr = attrs[i].split('=');
- key = attr[0];
- value = attr[1];
- switch (key) {
- case 'FREQ':
- options.freq = RRule[value];
- break;
- case 'WKST':
- options.wkst = RRule[value];
- break;
- case 'COUNT':
- case 'INTERVAL':
- case 'BYSETPOS':
- case 'BYMONTH':
- case 'BYMONTHDAY':
- case 'BYYEARDAY':
- case 'BYWEEKNO':
- case 'BYHOUR':
- case 'BYMINUTE':
- case 'BYSECOND':
- if (value.indexOf(',') != -1) {
- value = value.split(',');
- for (j = 0; j < value.length; j++) {
- if (/^[+-]?\d+$/.test(value[j])) {
- value[j] = Number(value[j]);
- }
- }
- } else if (/^[+-]?\d+$/.test(value)) {
- value = Number(value);
- }
- key = key.toLowerCase();
- options[key] = value;
- break;
- case 'BYDAY':
- var n, wday, day, days = value.split(',');
- options.byweekday = [];
- for (j = 0; j < days.length; j++) {
- day = days[j];
- if (day.length == 2) {
- wday = RRule[day];
- options.byweekday.push(wday);
- } else {
- day = day.match(/^([+-]?\d)([A-Z]{2})$/);
- n = Number(day[1]);
- wday = day[2];
- wday = RRule[wday].weekday;
- options.byweekday.push(new Weekday(wday, n));
- }
- }
- break;
- case 'DTSTART':
- options.dtstart = dateutil.untilStringToDate(value);
- break;
- case 'UNTIL':
- options.until = dateutil.untilStringToDate(value);
- break;
- case 'BYEASTER':
- options.byeaster = Number(value);
- break;
- default:
- throw new Error("Unknown RRULE property '" + key + "'");
- }
- }
- return options;
- };
- RRule.fromString = function(string) {
- return new RRule(RRule.parseString(string));
- };
- var Iterinfo = function(rrule) {
- this.rrule = rrule;
- this.lastyear = null;
- this.lastmonth = null;
- this.yearlen = null;
- this.nextyearlen = null;
- this.yearordinal = null;
- this.yearweekday = null;
- this.mmask = null;
- this.mrange = null;
- this.mdaymask = null;
- this.nmdaymask = null;
- this.wdaymask = null;
- this.wnomask = null;
- this.nwdaymask = null;
- this.eastermask = null;
- };
- Iterinfo.prototype.easter = function(y, offset) {
- offset = offset || 0;
- var a = y % 19,
- b = Math.floor(y / 100),
- c = y % 100,
- d = Math.floor(b / 4),
- e = b % 4,
- f = Math.floor((b + 8) / 25),
- g = Math.floor((b - f + 1) / 3),
- h = Math.floor(19 * a + b - d - g + 15) % 30,
- i = Math.floor(c / 4),
- k = c % 4,
- l = Math.floor(32 + 2 * e + 2 * i - h - k) % 7,
- m = Math.floor((a + 11 * h + 22 * l) / 451),
- month = Math.floor((h + l - 7 * m + 114) / 31),
- day = (h + l - 7 * m + 114) % 31 + 1,
- date = Date.UTC(y, month - 1, day + offset),
- yearStart = Date.UTC(y, 0, 1);
- return [ Math.ceil((date - yearStart) / (1000 * 60 * 60 * 24)) ];
- }
- Iterinfo.prototype.rebuild = function(year, month) {
- var rr = this.rrule;
- if (year != this.lastyear) {
- this.yearlen = dateutil.isLeapYear(year) ? 366 : 365;
- this.nextyearlen = dateutil.isLeapYear(year + 1) ? 366 : 365;
- var firstyday = new Date(year, 0, 1);
- this.yearordinal = dateutil.toOrdinal(firstyday);
- this.yearweekday = dateutil.getWeekday(firstyday);
- var wday = dateutil.getWeekday(new Date(year, 0, 1));
- if (this.yearlen == 365) {
- this.mmask = [].concat(M365MASK);
- this.mdaymask = [].concat(MDAY365MASK);
- this.nmdaymask = [].concat(NMDAY365MASK);
- this.wdaymask = WDAYMASK.slice(wday);
- this.mrange = [].concat(M365RANGE);
- } else {
- this.mmask = [].concat(M366MASK);
- this.mdaymask = [].concat(MDAY366MASK);
- this.nmdaymask = [].concat(NMDAY366MASK);
- this.wdaymask = WDAYMASK.slice(wday);
- this.mrange = [].concat(M366RANGE);
- }
- if (!plb(rr.options.byweekno)) {
- this.wnomask = null;
- } else {
- this.wnomask = repeat(0, this.yearlen + 7);
- var no1wkst, firstwkst, wyearlen;
- no1wkst = firstwkst = pymod(
- 7 - this.yearweekday + rr.options.wkst, 7);
- if (no1wkst >= 4) {
- no1wkst = 0;
-
-
- wyearlen = this.yearlen + pymod(
- this.yearweekday - rr.options.wkst, 7);
- } else {
-
-
- wyearlen = this.yearlen - no1wkst;
- }
- var div = Math.floor(wyearlen / 7);
- var mod = pymod(wyearlen, 7);
- var numweeks = Math.floor(div + (mod / 4));
- for (var n, i, j = 0; j < rr.options.byweekno.length; j++) {
- n = rr.options.byweekno[j];
- if (n < 0) {
- n += numweeks + 1;
- } if (!(0 < n && n <= numweeks)) {
- continue;
- } if (n > 1) {
- i = no1wkst + (n - 1) * 7;
- if (no1wkst != firstwkst) {
- i -= 7-firstwkst;
- }
- } else {
- i = no1wkst;
- }
- for (var k = 0; k < 7; k++) {
- this.wnomask[i] = 1;
- i++;
- if (this.wdaymask[i] == rr.options.wkst) {
- break;
- }
- }
- }
- if (contains(rr.options.byweekno, 1)) {
-
-
- var i = no1wkst + numweeks * 7;
- if (no1wkst != firstwkst) {
- i -= 7 - firstwkst;
- }
- if (i < this.yearlen) {
-
-
- for (var j = 0; j < 7; j++) {
- this.wnomask[i] = 1;
- i += 1;
- if (this.wdaymask[i] == rr.options.wkst) {
- break;
- }
- }
- }
- }
- if (no1wkst) {
-
-
-
-
-
-
- var lnumweeks;
- if (!contains(rr.options.byweekno, -1)) {
- var lyearweekday = dateutil.getWeekday(
- new Date(year - 1, 0, 1));
- var lno1wkst = pymod(
- 7 - lyearweekday + rr.options.wkst, 7);
- var lyearlen = dateutil.isLeapYear(year - 1) ? 366 : 365;
- if (lno1wkst >= 4) {
- lno1wkst = 0;
- lnumweeks = Math.floor(
- 52
- + pymod(
- lyearlen + pymod(
- lyearweekday - rr.options.wkst, 7), 7)
- / 4);
- } else {
- lnumweeks = Math.floor(
- 52 + pymod(this.yearlen - no1wkst, 7) / 4);
- }
- } else {
- lnumweeks = -1;
- }
- if (contains(rr.options.byweekno, lnumweeks)) {
- for (var i = 0; i < no1wkst; i++) {
- this.wnomask[i] = 1;
- }
- }
- }
- }
- }
- if (plb(rr.options.bynweekday)
- && (month != this.lastmonth || year != this.lastyear)) {
- var ranges = [];
- if (rr.options.freq == RRule.YEARLY) {
- if (plb(rr.options.bymonth)) {
- for (j = 0; j < rr.options.bymonth.length; j++) {
- month = rr.options.bymonth[j];
- ranges.push(this.mrange.slice(month - 1, month + 1));
- }
- } else {
- ranges = [[0, this.yearlen]];
- }
- } else if (rr.options.freq == RRule.MONTHLY) {
- ranges = [this.mrange.slice(month - 1, month + 1)];
- }
- if (plb(ranges)) {
-
-
- this.nwdaymask = repeat(0, this.yearlen);
- for (var j = 0; j < ranges.length; j++) {
- var rang = ranges[j];
- var first = rang[0], last = rang[1];
- last -= 1;
- for (var k = 0; k < rr.options.bynweekday.length; k++) {
- var wday = rr.options.bynweekday[k][0],
- n = rr.options.bynweekday[k][1];
- if (n < 0) {
- i = last + (n + 1) * 7;
- i -= pymod(this.wdaymask[i] - wday, 7);
- } else {
- i = first + (n - 1) * 7;
- i += pymod(7 - this.wdaymask[i] + wday, 7);
- }
- if (first <= i && i <= last) {
- this.nwdaymask[i] = 1;
- }
- }
- }
- }
- this.lastyear = year;
- this.lastmonth = month;
- }
- if (rr.options.byeaster !== null) {
- this.eastermask = this.easter(year, rr.options.byeaster);
- }
- };
- Iterinfo.prototype.ydayset = function(year, month, day) {
- return [range(this.yearlen), 0, this.yearlen];
- };
- Iterinfo.prototype.mdayset = function(year, month, day) {
- var set = repeat(null, this.yearlen);
- var start = this.mrange[month-1];
- var end = this.mrange[month];
- for (var i = start; i < end; i++) {
- set[i] = i;
- }
- return [set, start, end];
- };
- Iterinfo.prototype.wdayset = function(year, month, day) {
-
- var set = repeat(null, this.yearlen + 7);
- var i = dateutil.toOrdinal(
- new Date(year, month - 1, day)) - this.yearordinal;
- var start = i;
- for (var j = 0; j < 7; j++) {
- set[i] = i;
- ++i;
- if (this.wdaymask[i] == this.rrule.options.wkst) {
- break;
- }
- }
- return [set, start, i];
- };
- Iterinfo.prototype.ddayset = function(year, month, day) {
- var set = repeat(null, this.yearlen);
- var i = dateutil.toOrdinal(
- new Date(year, month - 1, day)) - this.yearordinal;
- set[i] = i;
- return [set, i, i + 1];
- };
- Iterinfo.prototype.htimeset = function(hour, minute, second) {
- var set = [], rr = this.rrule;
- for (var i = 0; i < rr.options.byminute.length; i++) {
- minute = rr.options.byminute[i];
- for (var j = 0; j < rr.options.bysecond.length; j++) {
- second = rr.options.bysecond[j];
- set.push(new dateutil.Time(hour, minute, second));
- }
- }
- dateutil.sort(set);
- return set;
- };
- Iterinfo.prototype.mtimeset = function(hour, minute, second) {
- var set = [], rr = this.rrule;
- for (var j = 0; j < rr.options.bysecond.length; j++) {
- second = rr.options.bysecond[j];
- set.push(new dateutil.Time(hour, minute, second));
- }
- dateutil.sort(set);
- return set;
- };
- Iterinfo.prototype.stimeset = function(hour, minute, second) {
- return [new dateutil.Time(hour, minute, second)];
- };
- var IterResult = function(method, args) {
- this.init(method, args)
- };
- IterResult.prototype = {
- init: function(method, args) {
- this.method = method;
- this.args = args;
- this._result = [];
- this.minDate = null;
- this.maxDate = null;
- if (method == 'between') {
- this.maxDate = args.inc
- ? args.before
- : new Date(args.before.getTime() - 1);
- this.minDate = args.inc
- ? args.after
- : new Date(args.after.getTime() + 1);
- } else if (method == 'before') {
- this.maxDate = args.inc ? args.dt : new Date(args.dt.getTime() - 1);
- } else if (method == 'after') {
- this.minDate = args.inc ? args.dt : new Date(args.dt.getTime() + 1);
- }
- },
-
- accept: function(date) {
- var tooEarly = this.minDate && date < this.minDate,
- tooLate = this.maxDate && date > this.maxDate;
- if (this.method == 'between') {
- if (tooEarly)
- return true;
- if (tooLate)
- return false;
- } else if (this.method == 'before') {
- if (tooLate)
- return false;
- } else if (this.method == 'after') {
- if (tooEarly)
- return true;
- this.add(date);
- return false;
- }
- return this.add(date);
- },
-
- add: function(date) {
- this._result.push(date);
- return true;
- },
-
- getValue: function() {
- switch (this.method) {
- case 'all':
- case 'between':
- return this._result;
- case 'before':
- case 'after':
- return this._result.length
- ? this._result[this._result.length - 1]
- : null;
- }
- }
- };
- var CallbackIterResult = function(method, args, iterator) {
- var allowedMethods = ['all', 'between'];
- if (!contains(allowedMethods, method)) {
- throw new Error('Invalid method "' + method
- + '". Only all and between works with iterator.');
- }
- this.add = function(date) {
- if (iterator(date, this._result.length)) {
- this._result.push(date);
- return true;
- }
- return false;
- };
- this.init(method, args);
- };
- CallbackIterResult.prototype = IterResult.prototype;
- if (serverSide) {
- module.exports = {
- RRule: RRule
-
- }
- }
- if (typeof ender === 'undefined') {
- root['RRule'] = RRule;
-
- }
- if (typeof define === "function" && define.amd) {
-
- define("rrule", [], function () {
- return RRule;
- });
- }
- }(this));
|