1667 lines
233 KiB
JavaScript
1667 lines
233 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
var pkg = require('../package.json');
|
||
|
var later = {
|
||
|
version: pkg.version
|
||
|
};
|
||
|
later.array = {};
|
||
|
later.array.sort = function (array, zeroIsLast) {
|
||
|
array.sort(function (a, b) {
|
||
|
return Number(a) - Number(b);
|
||
|
});
|
||
|
if (zeroIsLast && array[0] === 0) {
|
||
|
array.push(array.shift());
|
||
|
}
|
||
|
};
|
||
|
later.array.next = function (value, values, extent) {
|
||
|
var cur;
|
||
|
var zeroIsLargest = extent[0] !== 0;
|
||
|
var nextIdx = 0;
|
||
|
for (var i = values.length - 1; i > -1; --i) {
|
||
|
cur = values[i];
|
||
|
if (cur === value) {
|
||
|
return cur;
|
||
|
}
|
||
|
if (cur > value || cur === 0 && zeroIsLargest && extent[1] > value) {
|
||
|
nextIdx = i;
|
||
|
continue;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
return values[nextIdx];
|
||
|
};
|
||
|
later.array.nextInvalid = function (value, values, extent) {
|
||
|
var min = extent[0];
|
||
|
var max = extent[1];
|
||
|
var length = values.length;
|
||
|
var zeroValue = values[length - 1] === 0 && min !== 0 ? max : 0;
|
||
|
var next = value;
|
||
|
var i = values.indexOf(value);
|
||
|
var start = next;
|
||
|
while (next === (values[i] || zeroValue)) {
|
||
|
next++;
|
||
|
if (next > max) {
|
||
|
next = min;
|
||
|
}
|
||
|
i++;
|
||
|
if (i === length) {
|
||
|
i = 0;
|
||
|
}
|
||
|
if (next === start) {
|
||
|
return undefined;
|
||
|
}
|
||
|
}
|
||
|
return next;
|
||
|
};
|
||
|
later.array.prev = function (value, values, extent) {
|
||
|
var cur;
|
||
|
var length = values.length;
|
||
|
var zeroIsLargest = extent[0] !== 0;
|
||
|
var previousIdx = length - 1;
|
||
|
for (var i = 0; i < length; i++) {
|
||
|
cur = values[i];
|
||
|
if (cur === value) {
|
||
|
return cur;
|
||
|
}
|
||
|
if (cur < value || cur === 0 && zeroIsLargest && extent[1] < value) {
|
||
|
previousIdx = i;
|
||
|
continue;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
return values[previousIdx];
|
||
|
};
|
||
|
later.array.prevInvalid = function (value, values, extent) {
|
||
|
var min = extent[0];
|
||
|
var max = extent[1];
|
||
|
var length = values.length;
|
||
|
var zeroValue = values[length - 1] === 0 && min !== 0 ? max : 0;
|
||
|
var next = value;
|
||
|
var i = values.indexOf(value);
|
||
|
var start = next;
|
||
|
while (next === (values[i] || zeroValue)) {
|
||
|
next--;
|
||
|
if (next < min) {
|
||
|
next = max;
|
||
|
}
|
||
|
i--;
|
||
|
if (i === -1) {
|
||
|
i = length - 1;
|
||
|
}
|
||
|
if (next === start) {
|
||
|
return undefined;
|
||
|
}
|
||
|
}
|
||
|
return next;
|
||
|
};
|
||
|
later.day = later.D = {
|
||
|
name: 'day',
|
||
|
range: 86400,
|
||
|
val: function val(d) {
|
||
|
return d.D || (d.D = later.date.getDate.call(d));
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.D.val(d) === (value || later.D.extent(d)[1]);
|
||
|
},
|
||
|
extent: function extent(d) {
|
||
|
if (d.DExtent) return d.DExtent;
|
||
|
var month = later.M.val(d);
|
||
|
var max = later.DAYS_IN_MONTH[month - 1];
|
||
|
if (month === 2 && later.dy.extent(d)[1] === 366) {
|
||
|
max += 1;
|
||
|
}
|
||
|
return d.DExtent = [1, max];
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return d.DStart || (d.DStart = later.date.next(later.Y.val(d), later.M.val(d), later.D.val(d)));
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return d.DEnd || (d.DEnd = later.date.prev(later.Y.val(d), later.M.val(d), later.D.val(d)));
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
value = value > later.D.extent(d)[1] ? 1 : value;
|
||
|
var month = later.date.nextRollover(d, value, later.D, later.M);
|
||
|
var DMax = later.D.extent(month)[1];
|
||
|
value = value > DMax ? 1 : value || DMax;
|
||
|
return later.date.next(later.Y.val(month), later.M.val(month), value);
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
var month = later.date.prevRollover(d, value, later.D, later.M);
|
||
|
var DMax = later.D.extent(month)[1];
|
||
|
return later.date.prev(later.Y.val(month), later.M.val(month), value > DMax ? DMax : value || DMax);
|
||
|
}
|
||
|
};
|
||
|
later.dayOfWeekCount = later.dc = {
|
||
|
name: 'day of week count',
|
||
|
range: 604800,
|
||
|
val: function val(d) {
|
||
|
return d.dc || (d.dc = Math.floor((later.D.val(d) - 1) / 7) + 1);
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.dc.val(d) === value || value === 0 && later.D.val(d) > later.D.extent(d)[1] - 7;
|
||
|
},
|
||
|
extent: function extent(d) {
|
||
|
return d.dcExtent || (d.dcExtent = [1, Math.ceil(later.D.extent(d)[1] / 7)]);
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return d.dcStart || (d.dcStart = later.date.next(later.Y.val(d), later.M.val(d), Math.max(1, (later.dc.val(d) - 1) * 7 + 1 || 1)));
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return d.dcEnd || (d.dcEnd = later.date.prev(later.Y.val(d), later.M.val(d), Math.min(later.dc.val(d) * 7, later.D.extent(d)[1])));
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
value = value > later.dc.extent(d)[1] ? 1 : value;
|
||
|
var month = later.date.nextRollover(d, value, later.dc, later.M);
|
||
|
var dcMax = later.dc.extent(month)[1];
|
||
|
value = value > dcMax ? 1 : value;
|
||
|
var next = later.date.next(later.Y.val(month), later.M.val(month), value === 0 ? later.D.extent(month)[1] - 6 : 1 + 7 * (value - 1));
|
||
|
if (next.getTime() <= d.getTime()) {
|
||
|
month = later.M.next(d, later.M.val(d) + 1);
|
||
|
return later.date.next(later.Y.val(month), later.M.val(month), value === 0 ? later.D.extent(month)[1] - 6 : 1 + 7 * (value - 1));
|
||
|
}
|
||
|
return next;
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
var month = later.date.prevRollover(d, value, later.dc, later.M);
|
||
|
var dcMax = later.dc.extent(month)[1];
|
||
|
value = value > dcMax ? dcMax : value || dcMax;
|
||
|
return later.dc.end(later.date.prev(later.Y.val(month), later.M.val(month), 1 + 7 * (value - 1)));
|
||
|
}
|
||
|
};
|
||
|
later.dayOfWeek = later.dw = later.d = {
|
||
|
name: 'day of week',
|
||
|
range: 86400,
|
||
|
val: function val(d) {
|
||
|
return d.dw || (d.dw = later.date.getDay.call(d) + 1);
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.dw.val(d) === (value || 7);
|
||
|
},
|
||
|
extent: function extent() {
|
||
|
return [1, 7];
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return later.D.start(d);
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return later.D.end(d);
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
value = value > 7 ? 1 : value || 7;
|
||
|
return later.date.next(later.Y.val(d), later.M.val(d), later.D.val(d) + (value - later.dw.val(d)) + (value <= later.dw.val(d) ? 7 : 0));
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
value = value > 7 ? 7 : value || 7;
|
||
|
return later.date.prev(later.Y.val(d), later.M.val(d), later.D.val(d) + (value - later.dw.val(d)) + (value >= later.dw.val(d) ? -7 : 0));
|
||
|
}
|
||
|
};
|
||
|
later.dayOfYear = later.dy = {
|
||
|
name: 'day of year',
|
||
|
range: 86400,
|
||
|
val: function val(d) {
|
||
|
return d.dy || (d.dy = Math.ceil(1 + (later.D.start(d).getTime() - later.Y.start(d).getTime()) / later.DAY));
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.dy.val(d) === (value || later.dy.extent(d)[1]);
|
||
|
},
|
||
|
extent: function extent(d) {
|
||
|
var year = later.Y.val(d);
|
||
|
return d.dyExtent || (d.dyExtent = [1, year % 4 ? 365 : 366]);
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return later.D.start(d);
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return later.D.end(d);
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
value = value > later.dy.extent(d)[1] ? 1 : value;
|
||
|
var year = later.date.nextRollover(d, value, later.dy, later.Y);
|
||
|
var dyMax = later.dy.extent(year)[1];
|
||
|
value = value > dyMax ? 1 : value || dyMax;
|
||
|
return later.date.next(later.Y.val(year), later.M.val(year), value);
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
var year = later.date.prevRollover(d, value, later.dy, later.Y);
|
||
|
var dyMax = later.dy.extent(year)[1];
|
||
|
value = value > dyMax ? dyMax : value || dyMax;
|
||
|
return later.date.prev(later.Y.val(year), later.M.val(year), value);
|
||
|
}
|
||
|
};
|
||
|
later.hour = later.h = {
|
||
|
name: 'hour',
|
||
|
range: 3600,
|
||
|
val: function val(d) {
|
||
|
return d.h || (d.h = later.date.getHour.call(d));
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.h.val(d) === value;
|
||
|
},
|
||
|
extent: function extent() {
|
||
|
return [0, 23];
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return d.hStart || (d.hStart = later.date.next(later.Y.val(d), later.M.val(d), later.D.val(d), later.h.val(d)));
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return d.hEnd || (d.hEnd = later.date.prev(later.Y.val(d), later.M.val(d), later.D.val(d), later.h.val(d)));
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
value = value > 23 ? 0 : value;
|
||
|
var next = later.date.next(later.Y.val(d), later.M.val(d), later.D.val(d) + (value <= later.h.val(d) ? 1 : 0), value);
|
||
|
if (!later.date.isUTC && next.getTime() <= d.getTime()) {
|
||
|
next = later.date.next(later.Y.val(next), later.M.val(next), later.D.val(next), value + 1);
|
||
|
}
|
||
|
return next;
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
value = value > 23 ? 23 : value;
|
||
|
return later.date.prev(later.Y.val(d), later.M.val(d), later.D.val(d) + (value >= later.h.val(d) ? -1 : 0), value);
|
||
|
}
|
||
|
};
|
||
|
later.minute = later.m = {
|
||
|
name: 'minute',
|
||
|
range: 60,
|
||
|
val: function val(d) {
|
||
|
return d.m || (d.m = later.date.getMin.call(d));
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.m.val(d) === value;
|
||
|
},
|
||
|
extent: function extent(d) {
|
||
|
return [0, 59];
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return d.mStart || (d.mStart = later.date.next(later.Y.val(d), later.M.val(d), later.D.val(d), later.h.val(d), later.m.val(d)));
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return d.mEnd || (d.mEnd = later.date.prev(later.Y.val(d), later.M.val(d), later.D.val(d), later.h.val(d), later.m.val(d)));
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
var m = later.m.val(d);
|
||
|
var s = later.s.val(d);
|
||
|
var inc = value > 59 ? 60 - m : value <= m ? 60 - m + value : value - m;
|
||
|
var next = new Date(d.getTime() + inc * later.MIN - s * later.SEC);
|
||
|
if (!later.date.isUTC && next.getTime() <= d.getTime()) {
|
||
|
next = new Date(d.getTime() + (inc + 120) * later.MIN - s * later.SEC);
|
||
|
}
|
||
|
return next;
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
value = value > 59 ? 59 : value;
|
||
|
return later.date.prev(later.Y.val(d), later.M.val(d), later.D.val(d), later.h.val(d) + (value >= later.m.val(d) ? -1 : 0), value);
|
||
|
}
|
||
|
};
|
||
|
later.month = later.M = {
|
||
|
name: 'month',
|
||
|
range: 2629740,
|
||
|
val: function val(d) {
|
||
|
return d.M || (d.M = later.date.getMonth.call(d) + 1);
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.M.val(d) === (value || 12);
|
||
|
},
|
||
|
extent: function extent() {
|
||
|
return [1, 12];
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return d.MStart || (d.MStart = later.date.next(later.Y.val(d), later.M.val(d)));
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return d.MEnd || (d.MEnd = later.date.prev(later.Y.val(d), later.M.val(d)));
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
value = value > 12 ? 1 : value || 12;
|
||
|
return later.date.next(later.Y.val(d) + (value > later.M.val(d) ? 0 : 1), value);
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
value = value > 12 ? 12 : value || 12;
|
||
|
return later.date.prev(later.Y.val(d) - (value >= later.M.val(d) ? 1 : 0), value);
|
||
|
}
|
||
|
};
|
||
|
later.second = later.s = {
|
||
|
name: 'second',
|
||
|
range: 1,
|
||
|
val: function val(d) {
|
||
|
return d.s || (d.s = later.date.getSec.call(d));
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.s.val(d) === value;
|
||
|
},
|
||
|
extent: function extent() {
|
||
|
return [0, 59];
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return d;
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return d;
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
var s = later.s.val(d);
|
||
|
var inc = value > 59 ? 60 - s : value <= s ? 60 - s + value : value - s;
|
||
|
var next = new Date(d.getTime() + inc * later.SEC);
|
||
|
if (!later.date.isUTC && next.getTime() <= d.getTime()) {
|
||
|
next = new Date(d.getTime() + (inc + 7200) * later.SEC);
|
||
|
}
|
||
|
return next;
|
||
|
},
|
||
|
prev: function prev(d, value, cache) {
|
||
|
value = value > 59 ? 59 : value;
|
||
|
return later.date.prev(later.Y.val(d), later.M.val(d), later.D.val(d), later.h.val(d), later.m.val(d) + (value >= later.s.val(d) ? -1 : 0), value);
|
||
|
}
|
||
|
};
|
||
|
later.time = later.t = {
|
||
|
name: 'time',
|
||
|
range: 1,
|
||
|
val: function val(d) {
|
||
|
return d.t || (d.t = later.h.val(d) * 3600 + later.m.val(d) * 60 + later.s.val(d));
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.t.val(d) === value;
|
||
|
},
|
||
|
extent: function extent() {
|
||
|
return [0, 86399];
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return d;
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return d;
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
value = value > 86399 ? 0 : value;
|
||
|
var next = later.date.next(later.Y.val(d), later.M.val(d), later.D.val(d) + (value <= later.t.val(d) ? 1 : 0), 0, 0, value);
|
||
|
if (!later.date.isUTC && next.getTime() < d.getTime()) {
|
||
|
next = later.date.next(later.Y.val(next), later.M.val(next), later.D.val(next), later.h.val(next), later.m.val(next), value + 7200);
|
||
|
}
|
||
|
return next;
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
value = value > 86399 ? 86399 : value;
|
||
|
return later.date.next(later.Y.val(d), later.M.val(d), later.D.val(d) + (value >= later.t.val(d) ? -1 : 0), 0, 0, value);
|
||
|
}
|
||
|
};
|
||
|
later.weekOfMonth = later.wm = {
|
||
|
name: 'week of month',
|
||
|
range: 604800,
|
||
|
val: function val(d) {
|
||
|
return d.wm || (d.wm = (later.D.val(d) + (later.dw.val(later.M.start(d)) - 1) + (7 - later.dw.val(d))) / 7);
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.wm.val(d) === (value || later.wm.extent(d)[1]);
|
||
|
},
|
||
|
extent: function extent(d) {
|
||
|
return d.wmExtent || (d.wmExtent = [1, (later.D.extent(d)[1] + (later.dw.val(later.M.start(d)) - 1) + (7 - later.dw.val(later.M.end(d)))) / 7]);
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return d.wmStart || (d.wmStart = later.date.next(later.Y.val(d), later.M.val(d), Math.max(later.D.val(d) - later.dw.val(d) + 1, 1)));
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return d.wmEnd || (d.wmEnd = later.date.prev(later.Y.val(d), later.M.val(d), Math.min(later.D.val(d) + (7 - later.dw.val(d)), later.D.extent(d)[1])));
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
value = value > later.wm.extent(d)[1] ? 1 : value;
|
||
|
var month = later.date.nextRollover(d, value, later.wm, later.M);
|
||
|
var wmMax = later.wm.extent(month)[1];
|
||
|
value = value > wmMax ? 1 : value || wmMax;
|
||
|
return later.date.next(later.Y.val(month), later.M.val(month), Math.max(1, (value - 1) * 7 - (later.dw.val(month) - 2)));
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
var month = later.date.prevRollover(d, value, later.wm, later.M);
|
||
|
var wmMax = later.wm.extent(month)[1];
|
||
|
value = value > wmMax ? wmMax : value || wmMax;
|
||
|
return later.wm.end(later.date.next(later.Y.val(month), later.M.val(month), Math.max(1, (value - 1) * 7 - (later.dw.val(month) - 2))));
|
||
|
}
|
||
|
};
|
||
|
later.weekOfYear = later.wy = {
|
||
|
name: 'week of year (ISO)',
|
||
|
range: 604800,
|
||
|
val: function val(d) {
|
||
|
if (d.wy) return d.wy;
|
||
|
var wThur = later.dw.next(later.wy.start(d), 5);
|
||
|
var YThur = later.dw.next(later.Y.prev(wThur, later.Y.val(wThur) - 1), 5);
|
||
|
return d.wy = 1 + Math.ceil((wThur.getTime() - YThur.getTime()) / later.WEEK);
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.wy.val(d) === (value || later.wy.extent(d)[1]);
|
||
|
},
|
||
|
extent: function extent(d) {
|
||
|
if (d.wyExtent) return d.wyExtent;
|
||
|
var year = later.dw.next(later.wy.start(d), 5);
|
||
|
var dwFirst = later.dw.val(later.Y.start(year));
|
||
|
var dwLast = later.dw.val(later.Y.end(year));
|
||
|
return d.wyExtent = [1, dwFirst === 5 || dwLast === 5 ? 53 : 52];
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return d.wyStart || (d.wyStart = later.date.next(later.Y.val(d), later.M.val(d), later.D.val(d) - (later.dw.val(d) > 1 ? later.dw.val(d) - 2 : 6)));
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return d.wyEnd || (d.wyEnd = later.date.prev(later.Y.val(d), later.M.val(d), later.D.val(d) + (later.dw.val(d) > 1 ? 8 - later.dw.val(d) : 0)));
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
value = value > later.wy.extent(d)[1] ? 1 : value;
|
||
|
var wyThur = later.dw.next(later.wy.start(d), 5);
|
||
|
var year = later.date.nextRollover(wyThur, value, later.wy, later.Y);
|
||
|
if (later.wy.val(year) !== 1) {
|
||
|
year = later.dw.next(year, 2);
|
||
|
}
|
||
|
var wyMax = later.wy.extent(year)[1];
|
||
|
var wyStart = later.wy.start(year);
|
||
|
value = value > wyMax ? 1 : value || wyMax;
|
||
|
return later.date.next(later.Y.val(wyStart), later.M.val(wyStart), later.D.val(wyStart) + 7 * (value - 1));
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
var wyThur = later.dw.next(later.wy.start(d), 5);
|
||
|
var year = later.date.prevRollover(wyThur, value, later.wy, later.Y);
|
||
|
if (later.wy.val(year) !== 1) {
|
||
|
year = later.dw.next(year, 2);
|
||
|
}
|
||
|
var wyMax = later.wy.extent(year)[1];
|
||
|
var wyEnd = later.wy.end(year);
|
||
|
value = value > wyMax ? wyMax : value || wyMax;
|
||
|
return later.wy.end(later.date.next(later.Y.val(wyEnd), later.M.val(wyEnd), later.D.val(wyEnd) + 7 * (value - 1)));
|
||
|
}
|
||
|
};
|
||
|
later.year = later.Y = {
|
||
|
name: 'year',
|
||
|
range: 31556900,
|
||
|
val: function val(d) {
|
||
|
return d.Y || (d.Y = later.date.getYear.call(d));
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.Y.val(d) === value;
|
||
|
},
|
||
|
extent: function extent() {
|
||
|
return [1970, 2099];
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return d.YStart || (d.YStart = later.date.next(later.Y.val(d)));
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return d.YEnd || (d.YEnd = later.date.prev(later.Y.val(d)));
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
return value > later.Y.val(d) && value <= later.Y.extent()[1] ? later.date.next(value) : later.NEVER;
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
return value < later.Y.val(d) && value >= later.Y.extent()[0] ? later.date.prev(value) : later.NEVER;
|
||
|
}
|
||
|
};
|
||
|
later.fullDate = later.fd = {
|
||
|
name: 'full date',
|
||
|
range: 1,
|
||
|
val: function val(d) {
|
||
|
return d.fd || (d.fd = d.getTime());
|
||
|
},
|
||
|
isValid: function isValid(d, value) {
|
||
|
return later.fd.val(d) === value;
|
||
|
},
|
||
|
extent: function extent() {
|
||
|
return [0, 3250368e7];
|
||
|
},
|
||
|
start: function start(d) {
|
||
|
return d;
|
||
|
},
|
||
|
end: function end(d) {
|
||
|
return d;
|
||
|
},
|
||
|
next: function next(d, value) {
|
||
|
return later.fd.val(d) < value ? new Date(value) : later.NEVER;
|
||
|
},
|
||
|
prev: function prev(d, value) {
|
||
|
return later.fd.val(d) > value ? new Date(value) : later.NEVER;
|
||
|
}
|
||
|
};
|
||
|
later.modifier = {};
|
||
|
later.modifier.after = later.modifier.a = function (constraint, values) {
|
||
|
var value = values[0];
|
||
|
return {
|
||
|
name: 'after ' + constraint.name,
|
||
|
range: (constraint.extent(new Date())[1] - value) * constraint.range,
|
||
|
val: constraint.val,
|
||
|
isValid: function isValid(d, value_) {
|
||
|
return this.val(d) >= value;
|
||
|
},
|
||
|
extent: constraint.extent,
|
||
|
start: constraint.start,
|
||
|
end: constraint.end,
|
||
|
next: function next(startDate, value_) {
|
||
|
if (value_ != value) value_ = constraint.extent(startDate)[0];
|
||
|
return constraint.next(startDate, value_);
|
||
|
},
|
||
|
prev: function prev(startDate, value_) {
|
||
|
value_ = value_ === value ? constraint.extent(startDate)[1] : value - 1;
|
||
|
return constraint.prev(startDate, value_);
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
later.modifier.before = later.modifier.b = function (constraint, values) {
|
||
|
var value = values[values.length - 1];
|
||
|
return {
|
||
|
name: 'before ' + constraint.name,
|
||
|
range: constraint.range * (value - 1),
|
||
|
val: constraint.val,
|
||
|
isValid: function isValid(d, value_) {
|
||
|
return this.val(d) < value;
|
||
|
},
|
||
|
extent: constraint.extent,
|
||
|
start: constraint.start,
|
||
|
end: constraint.end,
|
||
|
next: function next(startDate, value_) {
|
||
|
value_ = value_ === value ? constraint.extent(startDate)[0] : value;
|
||
|
return constraint.next(startDate, value_);
|
||
|
},
|
||
|
prev: function prev(startDate, value_) {
|
||
|
value_ = value_ === value ? value - 1 : constraint.extent(startDate)[1];
|
||
|
return constraint.prev(startDate, value_);
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
later.compile = function (schedDef) {
|
||
|
var constraints = [];
|
||
|
var constraintsLength = 0;
|
||
|
var tickConstraint;
|
||
|
for (var key in schedDef) {
|
||
|
var nameParts = key.split('_');
|
||
|
var name = nameParts[0];
|
||
|
var mod = nameParts[1];
|
||
|
var vals = schedDef[key];
|
||
|
var constraint = mod ? later.modifier[mod](later[name], vals) : later[name];
|
||
|
constraints.push({
|
||
|
constraint: constraint,
|
||
|
vals: vals
|
||
|
});
|
||
|
constraintsLength++;
|
||
|
}
|
||
|
constraints.sort(function (a, b) {
|
||
|
var ra = a.constraint.range;
|
||
|
var rb = b.constraint.range;
|
||
|
return rb < ra ? -1 : rb > ra ? 1 : 0;
|
||
|
});
|
||
|
tickConstraint = constraints[constraintsLength - 1].constraint;
|
||
|
function compareFn(dir) {
|
||
|
return dir === 'next' ? function (a, b) {
|
||
|
if (!a || !b) return true;
|
||
|
return a.getTime() > b.getTime();
|
||
|
} : function (a, b) {
|
||
|
if (!a || !b) return true;
|
||
|
return b.getTime() > a.getTime();
|
||
|
};
|
||
|
}
|
||
|
return {
|
||
|
start: function start(dir, startDate) {
|
||
|
var next = startDate;
|
||
|
var nextValue = later.array[dir];
|
||
|
var maxAttempts = 1e3;
|
||
|
var done;
|
||
|
while (maxAttempts-- && !done && next) {
|
||
|
done = true;
|
||
|
for (var i = 0; i < constraintsLength; i++) {
|
||
|
var _constraint = constraints[i].constraint;
|
||
|
var curValue = _constraint.val(next);
|
||
|
var extent = _constraint.extent(next);
|
||
|
var newValue = nextValue(curValue, constraints[i].vals, extent);
|
||
|
if (!_constraint.isValid(next, newValue)) {
|
||
|
next = _constraint[dir](next, newValue);
|
||
|
done = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (next !== later.NEVER) {
|
||
|
next = dir === 'next' ? tickConstraint.start(next) : tickConstraint.end(next);
|
||
|
}
|
||
|
return next;
|
||
|
},
|
||
|
end: function end(dir, startDate) {
|
||
|
var result;
|
||
|
var nextValue = later.array[dir + 'Invalid'];
|
||
|
var compare = compareFn(dir);
|
||
|
for (var i = constraintsLength - 1; i >= 0; i--) {
|
||
|
var _constraint2 = constraints[i].constraint;
|
||
|
var curValue = _constraint2.val(startDate);
|
||
|
var extent = _constraint2.extent(startDate);
|
||
|
var newValue = nextValue(curValue, constraints[i].vals, extent);
|
||
|
var next;
|
||
|
if (newValue !== undefined) {
|
||
|
next = _constraint2[dir](startDate, newValue);
|
||
|
if (next && (!result || compare(result, next))) {
|
||
|
result = next;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
},
|
||
|
tick: function tick(dir, date) {
|
||
|
return new Date(dir === 'next' ? tickConstraint.end(date).getTime() + later.SEC : tickConstraint.start(date).getTime() - later.SEC);
|
||
|
},
|
||
|
tickStart: function tickStart(date) {
|
||
|
return tickConstraint.start(date);
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
later.schedule = function (sched) {
|
||
|
if (!sched) throw new Error('Missing schedule definition.');
|
||
|
if (!sched.schedules) throw new Error('Definition must include at least one schedule.');
|
||
|
var schedules = [];
|
||
|
var schedulesLength = sched.schedules.length;
|
||
|
var exceptions = [];
|
||
|
var exceptionsLength = sched.exceptions ? sched.exceptions.length : 0;
|
||
|
for (var i = 0; i < schedulesLength; i++) {
|
||
|
schedules.push(later.compile(sched.schedules[i]));
|
||
|
}
|
||
|
for (var j = 0; j < exceptionsLength; j++) {
|
||
|
exceptions.push(later.compile(sched.exceptions[j]));
|
||
|
}
|
||
|
function getInstances(dir, count, startDate, endDate, isRange) {
|
||
|
var compare = compareFn(dir);
|
||
|
var loopCount = count;
|
||
|
var maxAttempts = 1e3;
|
||
|
var schedStarts = [];
|
||
|
var exceptStarts = [];
|
||
|
var next;
|
||
|
var end;
|
||
|
var results = [];
|
||
|
var isForward = dir === 'next';
|
||
|
var lastResult;
|
||
|
var rStart = isForward ? 0 : 1;
|
||
|
var rEnd = isForward ? 1 : 0;
|
||
|
startDate = startDate ? new Date(startDate) : new Date();
|
||
|
if (!startDate || !startDate.getTime()) throw new Error('Invalid start date.');
|
||
|
setNextStarts(dir, schedules, schedStarts, startDate);
|
||
|
setRangeStarts(dir, exceptions, exceptStarts, startDate);
|
||
|
while (maxAttempts-- && loopCount && (next = findNext(schedStarts, compare))) {
|
||
|
if (endDate && compare(next, endDate)) {
|
||
|
break;
|
||
|
}
|
||
|
if (exceptionsLength) {
|
||
|
updateRangeStarts(dir, exceptions, exceptStarts, next);
|
||
|
if (end = calcRangeOverlap(dir, exceptStarts, next)) {
|
||
|
updateNextStarts(dir, schedules, schedStarts, end);
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
if (isRange) {
|
||
|
var maxEndDate = calcMaxEndDate(exceptStarts, compare);
|
||
|
end = calcEnd(dir, schedules, schedStarts, next, maxEndDate);
|
||
|
var r = isForward ? [new Date(Math.max(startDate, next)), end ? new Date(endDate ? Math.min(end, endDate) : end) : undefined] : [end ? new Date(endDate ? Math.max(endDate, end.getTime() + later.SEC) : end.getTime() + later.SEC) : undefined, new Date(Math.min(startDate, next.getTime() + later.SEC))];
|
||
|
if (lastResult && r[rStart].getTime() === lastResult[rEnd].getTime()) {
|
||
|
lastResult[rEnd] = r[rEnd];
|
||
|
loopCount++;
|
||
|
} else {
|
||
|
lastResult = r;
|
||
|
results.push(lastResult);
|
||
|
}
|
||
|
if (!end) break;
|
||
|
updateNextStarts(dir, schedules, schedStarts, end);
|
||
|
} else {
|
||
|
results.push(isForward ? new Date(Math.max(startDate, next)) : getStart(schedules, schedStarts, next, endDate));
|
||
|
tickStarts(dir, schedules, schedStarts, next);
|
||
|
}
|
||
|
loopCount--;
|
||
|
}
|
||
|
for (var _i = 0, length = results.length; _i < length; _i++) {
|
||
|
var result = results[_i];
|
||
|
results[_i] = Object.prototype.toString.call(result) === '[object Array]' ? [cleanDate(result[0]), cleanDate(result[1])] : cleanDate(result);
|
||
|
}
|
||
|
return results.length === 0 ? later.NEVER : count === 1 ? results[0] : results;
|
||
|
}
|
||
|
function cleanDate(d) {
|
||
|
if (d instanceof Date && !isNaN(d.valueOf())) {
|
||
|
return new Date(d);
|
||
|
}
|
||
|
return undefined;
|
||
|
}
|
||
|
function setNextStarts(dir, schedArray, startsArray, startDate) {
|
||
|
for (var _i2 = 0, length = schedArray.length; _i2 < length; _i2++) {
|
||
|
startsArray[_i2] = schedArray[_i2].start(dir, startDate);
|
||
|
}
|
||
|
}
|
||
|
function updateNextStarts(dir, schedArray, startsArray, startDate) {
|
||
|
var compare = compareFn(dir);
|
||
|
for (var _i3 = 0, length = schedArray.length; _i3 < length; _i3++) {
|
||
|
if (startsArray[_i3] && !compare(startsArray[_i3], startDate)) {
|
||
|
startsArray[_i3] = schedArray[_i3].start(dir, startDate);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function setRangeStarts(dir, schedArray, rangesArray, startDate) {
|
||
|
var compare = compareFn(dir);
|
||
|
for (var _i4 = 0, length = schedArray.length; _i4 < length; _i4++) {
|
||
|
var nextStart = schedArray[_i4].start(dir, startDate);
|
||
|
if (!nextStart) {
|
||
|
rangesArray[_i4] = later.NEVER;
|
||
|
} else {
|
||
|
rangesArray[_i4] = [nextStart, schedArray[_i4].end(dir, nextStart)];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function updateRangeStarts(dir, schedArray, rangesArray, startDate) {
|
||
|
var compare = compareFn(dir);
|
||
|
for (var _i5 = 0, length = schedArray.length; _i5 < length; _i5++) {
|
||
|
if (rangesArray[_i5] && !compare(rangesArray[_i5][0], startDate)) {
|
||
|
var nextStart = schedArray[_i5].start(dir, startDate);
|
||
|
if (!nextStart) {
|
||
|
rangesArray[_i5] = later.NEVER;
|
||
|
} else {
|
||
|
rangesArray[_i5] = [nextStart, schedArray[_i5].end(dir, nextStart)];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function tickStarts(dir, schedArray, startsArray, startDate) {
|
||
|
for (var _i6 = 0, length = schedArray.length; _i6 < length; _i6++) {
|
||
|
if (startsArray[_i6] && startsArray[_i6].getTime() === startDate.getTime()) {
|
||
|
startsArray[_i6] = schedArray[_i6].start(dir, schedArray[_i6].tick(dir, startDate));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function getStart(schedArray, startsArray, startDate, minEndDate) {
|
||
|
var result;
|
||
|
for (var _i7 = 0, length = startsArray.length; _i7 < length; _i7++) {
|
||
|
if (startsArray[_i7] && startsArray[_i7].getTime() === startDate.getTime()) {
|
||
|
var start = schedArray[_i7].tickStart(startDate);
|
||
|
if (minEndDate && start < minEndDate) {
|
||
|
return minEndDate;
|
||
|
}
|
||
|
if (!result || start > result) {
|
||
|
result = start;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function calcRangeOverlap(dir, rangesArray, startDate) {
|
||
|
var compare = compareFn(dir);
|
||
|
var result;
|
||
|
for (var _i8 = 0, length = rangesArray.length; _i8 < length; _i8++) {
|
||
|
var range = rangesArray[_i8];
|
||
|
if (range && !compare(range[0], startDate) && (!range[1] || compare(range[1], startDate))) {
|
||
|
if (!result || compare(range[1], result)) {
|
||
|
result = range[1];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function calcMaxEndDate(exceptsArray, compare) {
|
||
|
var result;
|
||
|
for (var _i9 = 0, length = exceptsArray.length; _i9 < length; _i9++) {
|
||
|
if (exceptsArray[_i9] && (!result || compare(result, exceptsArray[_i9][0]))) {
|
||
|
result = exceptsArray[_i9][0];
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function calcEnd(dir, schedArray, startsArray, startDate, maxEndDate) {
|
||
|
var compare = compareFn(dir);
|
||
|
var result;
|
||
|
for (var _i10 = 0, length = schedArray.length; _i10 < length; _i10++) {
|
||
|
var start = startsArray[_i10];
|
||
|
if (start && start.getTime() === startDate.getTime()) {
|
||
|
var end = schedArray[_i10].end(dir, start);
|
||
|
if (maxEndDate && (!end || compare(end, maxEndDate))) {
|
||
|
return maxEndDate;
|
||
|
}
|
||
|
if (!result || compare(end, result)) {
|
||
|
result = end;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function compareFn(dir) {
|
||
|
return dir === 'next' ? function (a, b) {
|
||
|
if (!a || !b) return true;
|
||
|
return a.getTime() > b.getTime();
|
||
|
} : function (a, b) {
|
||
|
if (!a || !b) return true;
|
||
|
return b.getTime() > a.getTime();
|
||
|
};
|
||
|
}
|
||
|
function findNext(array, compare) {
|
||
|
var next = array[0];
|
||
|
for (var _i11 = 1, length = array.length; _i11 < length; _i11++) {
|
||
|
if (array[_i11] && compare(next, array[_i11])) {
|
||
|
next = array[_i11];
|
||
|
}
|
||
|
}
|
||
|
return next;
|
||
|
}
|
||
|
return {
|
||
|
isValid: function isValid(d) {
|
||
|
return getInstances('next', 1, d, d) !== later.NEVER;
|
||
|
},
|
||
|
next: function next(count, startDate, endDate) {
|
||
|
return getInstances('next', count || 1, startDate, endDate);
|
||
|
},
|
||
|
prev: function prev(count, startDate, endDate) {
|
||
|
return getInstances('prev', count || 1, startDate, endDate);
|
||
|
},
|
||
|
nextRange: function nextRange(count, startDate, endDate) {
|
||
|
return getInstances('next', count || 1, startDate, endDate, true);
|
||
|
},
|
||
|
prevRange: function prevRange(count, startDate, endDate) {
|
||
|
return getInstances('prev', count || 1, startDate, endDate, true);
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
later.setTimeout = function (fn, sched, timezone) {
|
||
|
var s = later.schedule(sched);
|
||
|
var t;
|
||
|
if (fn) {
|
||
|
scheduleTimeout();
|
||
|
}
|
||
|
function scheduleTimeout() {
|
||
|
var date = new Date();
|
||
|
var now = date.getTime();
|
||
|
var next = function () {
|
||
|
if (!timezone || ['local', 'system'].includes(timezone)) {
|
||
|
return s.next(2, now);
|
||
|
}
|
||
|
var localOffsetMillis = date.getTimezoneOffset() * 6e4;
|
||
|
var offsetMillis = getOffset(date, timezone);
|
||
|
|
||
|
// Specified timezone has the same offset as local timezone.
|
||
|
// ie. America/New_York = America/Nassau = GMT-4
|
||
|
if (offsetMillis === localOffsetMillis) {
|
||
|
return s.next(2, now);
|
||
|
}
|
||
|
|
||
|
// Offsets differ, adjust current time to match what
|
||
|
// it should've been for the specified timezone.
|
||
|
var adjustedNow = new Date(now + localOffsetMillis - offsetMillis);
|
||
|
return (s.next(2, adjustedNow) || /* istanbul ignore next */[]).map(function (sched) {
|
||
|
// adjust scheduled times to match their intended timezone
|
||
|
// ie. scheduled = 2021-08-22T11:30:00.000-04:00 => America/New_York
|
||
|
// intended = 2021-08-22T11:30:00.000-05:00 => America/Mexico_City
|
||
|
return new Date(sched.getTime() + offsetMillis - localOffsetMillis);
|
||
|
});
|
||
|
}();
|
||
|
if (!next[0]) {
|
||
|
t = undefined;
|
||
|
return;
|
||
|
}
|
||
|
var diff = next[0].getTime() - now;
|
||
|
if (diff < 1e3) {
|
||
|
diff = next[1] ? next[1].getTime() - now : 1e3;
|
||
|
}
|
||
|
t = diff < 2147483647 ? setTimeout(fn, diff) : setTimeout(scheduleTimeout, 2147483647);
|
||
|
} // scheduleTimeout()
|
||
|
|
||
|
return {
|
||
|
isDone: function isDone() {
|
||
|
return !t;
|
||
|
},
|
||
|
clear: function clear() {
|
||
|
clearTimeout(t);
|
||
|
}
|
||
|
};
|
||
|
}; // setTimeout()
|
||
|
|
||
|
later.setInterval = function (fn, sched, timezone) {
|
||
|
if (!fn) {
|
||
|
return;
|
||
|
}
|
||
|
var t = later.setTimeout(scheduleTimeout, sched, timezone);
|
||
|
var done = t.isDone();
|
||
|
function scheduleTimeout() {
|
||
|
/* istanbul ignore else */
|
||
|
if (!done) {
|
||
|
fn();
|
||
|
t = later.setTimeout(scheduleTimeout, sched, timezone);
|
||
|
}
|
||
|
}
|
||
|
return {
|
||
|
isDone: function isDone() {
|
||
|
return t.isDone();
|
||
|
},
|
||
|
clear: function clear() {
|
||
|
done = true;
|
||
|
t.clear();
|
||
|
}
|
||
|
};
|
||
|
}; // setInterval()
|
||
|
|
||
|
later.date = {};
|
||
|
later.date.timezone = function (useLocalTime) {
|
||
|
later.date.build = useLocalTime ? function (Y, M, D, h, m, s) {
|
||
|
return new Date(Y, M, D, h, m, s);
|
||
|
} : function (Y, M, D, h, m, s) {
|
||
|
return new Date(Date.UTC(Y, M, D, h, m, s));
|
||
|
};
|
||
|
var get = useLocalTime ? 'get' : 'getUTC';
|
||
|
var d = Date.prototype;
|
||
|
later.date.getYear = d[get + 'FullYear'];
|
||
|
later.date.getMonth = d[get + 'Month'];
|
||
|
later.date.getDate = d[get + 'Date'];
|
||
|
later.date.getDay = d[get + 'Day'];
|
||
|
later.date.getHour = d[get + 'Hours'];
|
||
|
later.date.getMin = d[get + 'Minutes'];
|
||
|
later.date.getSec = d[get + 'Seconds'];
|
||
|
later.date.isUTC = !useLocalTime;
|
||
|
};
|
||
|
later.date.UTC = function () {
|
||
|
later.date.timezone(false);
|
||
|
};
|
||
|
later.date.localTime = function () {
|
||
|
later.date.timezone(true);
|
||
|
};
|
||
|
later.date.UTC();
|
||
|
later.SEC = 1e3;
|
||
|
later.MIN = later.SEC * 60;
|
||
|
later.HOUR = later.MIN * 60;
|
||
|
later.DAY = later.HOUR * 24;
|
||
|
later.WEEK = later.DAY * 7;
|
||
|
later.DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||
|
later.NEVER = 0;
|
||
|
later.date.next = function (Y, M, D, h, m, s) {
|
||
|
return later.date.build(Y, M !== undefined ? M - 1 : 0, D !== undefined ? D : 1, h || 0, m || 0, s || 0);
|
||
|
};
|
||
|
later.date.nextRollover = function (d, value, constraint, period) {
|
||
|
var cur = constraint.val(d);
|
||
|
var max = constraint.extent(d)[1];
|
||
|
return (value || max) <= cur || value > max ? new Date(period.end(d).getTime() + later.SEC) : period.start(d);
|
||
|
};
|
||
|
later.date.prev = function (Y, M, D, h, m, s) {
|
||
|
var length = arguments.length;
|
||
|
M = length < 2 ? 11 : M - 1;
|
||
|
D = length < 3 ? later.D.extent(later.date.next(Y, M + 1))[1] : D;
|
||
|
h = length < 4 ? 23 : h;
|
||
|
m = length < 5 ? 59 : m;
|
||
|
s = length < 6 ? 59 : s;
|
||
|
return later.date.build(Y, M, D, h, m, s);
|
||
|
};
|
||
|
later.date.prevRollover = function (d, value, constraint, period) {
|
||
|
var cur = constraint.val(d);
|
||
|
return value >= cur || !value ? period.start(period.prev(d, period.val(d) - 1)) : period.start(d);
|
||
|
};
|
||
|
later.parse = {};
|
||
|
later.parse.cron = function (expr, hasSeconds) {
|
||
|
var NAMES = {
|
||
|
JAN: 1,
|
||
|
FEB: 2,
|
||
|
MAR: 3,
|
||
|
APR: 4,
|
||
|
MAY: 5,
|
||
|
JUN: 6,
|
||
|
JUL: 7,
|
||
|
AUG: 8,
|
||
|
SEP: 9,
|
||
|
OCT: 10,
|
||
|
NOV: 11,
|
||
|
DEC: 12,
|
||
|
SUN: 1,
|
||
|
MON: 2,
|
||
|
TUE: 3,
|
||
|
WED: 4,
|
||
|
THU: 5,
|
||
|
FRI: 6,
|
||
|
SAT: 7
|
||
|
};
|
||
|
var REPLACEMENTS = {
|
||
|
'* * * * * *': '0/1 * * * * *',
|
||
|
'@YEARLY': '0 0 1 1 *',
|
||
|
'@ANNUALLY': '0 0 1 1 *',
|
||
|
'@MONTHLY': '0 0 1 * *',
|
||
|
'@WEEKLY': '0 0 * * 0',
|
||
|
'@DAILY': '0 0 * * *',
|
||
|
'@HOURLY': '0 * * * *'
|
||
|
};
|
||
|
var FIELDS = {
|
||
|
s: [0, 0, 59],
|
||
|
m: [1, 0, 59],
|
||
|
h: [2, 0, 23],
|
||
|
D: [3, 1, 31],
|
||
|
M: [4, 1, 12],
|
||
|
Y: [6, 1970, 2099],
|
||
|
d: [5, 1, 7, 1]
|
||
|
};
|
||
|
function getValue(value, offset, max) {
|
||
|
return isNaN(value) ? NAMES[value] || null : Math.min(Number(value) + (offset || 0), max || 9999);
|
||
|
}
|
||
|
function cloneSchedule(sched) {
|
||
|
var clone = {};
|
||
|
var field;
|
||
|
for (field in sched) {
|
||
|
if (field !== 'dc' && field !== 'd') {
|
||
|
clone[field] = sched[field].slice(0);
|
||
|
}
|
||
|
}
|
||
|
return clone;
|
||
|
}
|
||
|
function add(sched, name, min, max, inc) {
|
||
|
var i = min;
|
||
|
if (!sched[name]) {
|
||
|
sched[name] = [];
|
||
|
}
|
||
|
while (i <= max) {
|
||
|
if (!sched[name].includes(i)) {
|
||
|
sched[name].push(i);
|
||
|
}
|
||
|
i += inc || 1;
|
||
|
}
|
||
|
sched[name].sort(function (a, b) {
|
||
|
return a - b;
|
||
|
});
|
||
|
}
|
||
|
function addHash(schedules, curSched, value, hash) {
|
||
|
if (curSched.d && !curSched.dc || curSched.dc && !curSched.dc.includes(hash)) {
|
||
|
schedules.push(cloneSchedule(curSched));
|
||
|
curSched = schedules[schedules.length - 1];
|
||
|
}
|
||
|
add(curSched, 'd', value, value);
|
||
|
add(curSched, 'dc', hash, hash);
|
||
|
}
|
||
|
function addWeekday(s, curSched, value) {
|
||
|
var except1 = {};
|
||
|
var except2 = {};
|
||
|
if (value === 1) {
|
||
|
add(curSched, 'D', 1, 3);
|
||
|
add(curSched, 'd', NAMES.MON, NAMES.FRI);
|
||
|
add(except1, 'D', 2, 2);
|
||
|
add(except1, 'd', NAMES.TUE, NAMES.FRI);
|
||
|
add(except2, 'D', 3, 3);
|
||
|
add(except2, 'd', NAMES.TUE, NAMES.FRI);
|
||
|
} else {
|
||
|
add(curSched, 'D', value - 1, value + 1);
|
||
|
add(curSched, 'd', NAMES.MON, NAMES.FRI);
|
||
|
add(except1, 'D', value - 1, value - 1);
|
||
|
add(except1, 'd', NAMES.MON, NAMES.THU);
|
||
|
add(except2, 'D', value + 1, value + 1);
|
||
|
add(except2, 'd', NAMES.TUE, NAMES.FRI);
|
||
|
}
|
||
|
s.exceptions.push(except1);
|
||
|
s.exceptions.push(except2);
|
||
|
}
|
||
|
function addRange(item, curSched, name, min, max, offset) {
|
||
|
var incSplit = item.split('/');
|
||
|
var inc = Number(incSplit[1]);
|
||
|
var range = incSplit[0];
|
||
|
if (range !== '*' && range !== '0') {
|
||
|
var rangeSplit = range.split('-');
|
||
|
min = getValue(rangeSplit[0], offset, max);
|
||
|
max = getValue(rangeSplit[1], offset, max) || max;
|
||
|
}
|
||
|
add(curSched, name, min, max, inc);
|
||
|
}
|
||
|
function parse(item, s, name, min, max, offset) {
|
||
|
var value;
|
||
|
var split;
|
||
|
var schedules = s.schedules;
|
||
|
var curSched = schedules[schedules.length - 1];
|
||
|
if (item === 'L') {
|
||
|
item = min - 1;
|
||
|
}
|
||
|
if ((value = getValue(item, offset, max)) !== null) {
|
||
|
add(curSched, name, value, value);
|
||
|
} else if ((value = getValue(item.replace('W', ''), offset, max)) !== null) {
|
||
|
addWeekday(s, curSched, value);
|
||
|
} else if ((value = getValue(item.replace('L', ''), offset, max)) !== null) {
|
||
|
addHash(schedules, curSched, value, min - 1);
|
||
|
} else if ((split = item.split('#')).length === 2) {
|
||
|
value = getValue(split[0], offset, max);
|
||
|
addHash(schedules, curSched, value, getValue(split[1]));
|
||
|
} else {
|
||
|
addRange(item, curSched, name, min, max, offset);
|
||
|
}
|
||
|
}
|
||
|
function isHash(item) {
|
||
|
return item.includes('#') || item.indexOf('L') > 0;
|
||
|
}
|
||
|
function itemSorter(a, b) {
|
||
|
return isHash(a) && !isHash(b) ? 1 : a - b;
|
||
|
}
|
||
|
function parseExpr(expr) {
|
||
|
var schedule = {
|
||
|
schedules: [{}],
|
||
|
exceptions: []
|
||
|
};
|
||
|
var components = expr.replace(/(\s)+/g, ' ').split(' ');
|
||
|
var field;
|
||
|
var f;
|
||
|
var component;
|
||
|
var items;
|
||
|
for (field in FIELDS) {
|
||
|
f = FIELDS[field];
|
||
|
component = components[f[0]];
|
||
|
if (component && component !== '*' && component !== '?') {
|
||
|
items = component.split(',').sort(itemSorter);
|
||
|
var i;
|
||
|
var _items = items,
|
||
|
length = _items.length;
|
||
|
for (i = 0; i < length; i++) {
|
||
|
parse(items[i], schedule, field, f[1], f[2], f[3]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return schedule;
|
||
|
}
|
||
|
function prepareExpr(expr) {
|
||
|
var prepared = expr.toUpperCase();
|
||
|
return REPLACEMENTS[prepared] || prepared;
|
||
|
}
|
||
|
var e = prepareExpr(expr);
|
||
|
return parseExpr(hasSeconds ? e : '0 ' + e);
|
||
|
};
|
||
|
later.parse.recur = function () {
|
||
|
var schedules = [];
|
||
|
var exceptions = [];
|
||
|
var cur;
|
||
|
var curArray = schedules;
|
||
|
var curName;
|
||
|
var values;
|
||
|
var _every;
|
||
|
var modifier;
|
||
|
var applyMin;
|
||
|
var applyMax;
|
||
|
var i;
|
||
|
var last;
|
||
|
function add(name, min, max) {
|
||
|
name = modifier ? name + '_' + modifier : name;
|
||
|
if (!cur) {
|
||
|
curArray.push({});
|
||
|
cur = curArray[0];
|
||
|
}
|
||
|
if (!cur[name]) {
|
||
|
cur[name] = [];
|
||
|
}
|
||
|
curName = cur[name];
|
||
|
if (_every) {
|
||
|
values = [];
|
||
|
for (i = min; i <= max; i += _every) {
|
||
|
values.push(i);
|
||
|
}
|
||
|
last = {
|
||
|
n: name,
|
||
|
x: _every,
|
||
|
c: curName.length,
|
||
|
m: max
|
||
|
};
|
||
|
}
|
||
|
values = applyMin ? [min] : applyMax ? [max] : values;
|
||
|
var _values = values,
|
||
|
length = _values.length;
|
||
|
for (i = 0; i < length; i += 1) {
|
||
|
var value = values[i];
|
||
|
if (!curName.includes(value)) {
|
||
|
curName.push(value);
|
||
|
}
|
||
|
}
|
||
|
values = _every = modifier = applyMin = applyMax = 0;
|
||
|
}
|
||
|
return {
|
||
|
schedules: schedules,
|
||
|
exceptions: exceptions,
|
||
|
on: function on() {
|
||
|
values = Array.isArray(arguments[0]) ? arguments[0] : arguments;
|
||
|
return this;
|
||
|
},
|
||
|
every: function every(x) {
|
||
|
_every = x || 1;
|
||
|
return this;
|
||
|
},
|
||
|
after: function after(x) {
|
||
|
modifier = 'a';
|
||
|
values = [x];
|
||
|
return this;
|
||
|
},
|
||
|
before: function before(x) {
|
||
|
modifier = 'b';
|
||
|
values = [x];
|
||
|
return this;
|
||
|
},
|
||
|
first: function first() {
|
||
|
applyMin = 1;
|
||
|
return this;
|
||
|
},
|
||
|
last: function last() {
|
||
|
applyMax = 1;
|
||
|
return this;
|
||
|
},
|
||
|
time: function time() {
|
||
|
for (var _i12 = 0, _values2 = values, length = _values2.length; _i12 < length; _i12++) {
|
||
|
var split = values[_i12].split(':');
|
||
|
if (split.length < 3) split.push(0);
|
||
|
values[_i12] = Number(split[0]) * 3600 + Number(split[1]) * 60 + Number(split[2]);
|
||
|
}
|
||
|
add('t');
|
||
|
return this;
|
||
|
},
|
||
|
second: function second() {
|
||
|
add('s', 0, 59);
|
||
|
return this;
|
||
|
},
|
||
|
minute: function minute() {
|
||
|
add('m', 0, 59);
|
||
|
return this;
|
||
|
},
|
||
|
hour: function hour() {
|
||
|
add('h', 0, 23);
|
||
|
return this;
|
||
|
},
|
||
|
dayOfMonth: function dayOfMonth() {
|
||
|
add('D', 1, applyMax ? 0 : 31);
|
||
|
return this;
|
||
|
},
|
||
|
dayOfWeek: function dayOfWeek() {
|
||
|
add('d', 1, 7);
|
||
|
return this;
|
||
|
},
|
||
|
onWeekend: function onWeekend() {
|
||
|
values = [1, 7];
|
||
|
return this.dayOfWeek();
|
||
|
},
|
||
|
onWeekday: function onWeekday() {
|
||
|
values = [2, 3, 4, 5, 6];
|
||
|
return this.dayOfWeek();
|
||
|
},
|
||
|
dayOfWeekCount: function dayOfWeekCount() {
|
||
|
add('dc', 1, applyMax ? 0 : 5);
|
||
|
return this;
|
||
|
},
|
||
|
dayOfYear: function dayOfYear() {
|
||
|
add('dy', 1, applyMax ? 0 : 366);
|
||
|
return this;
|
||
|
},
|
||
|
weekOfMonth: function weekOfMonth() {
|
||
|
add('wm', 1, applyMax ? 0 : 5);
|
||
|
return this;
|
||
|
},
|
||
|
weekOfYear: function weekOfYear() {
|
||
|
add('wy', 1, applyMax ? 0 : 53);
|
||
|
return this;
|
||
|
},
|
||
|
month: function month() {
|
||
|
add('M', 1, 12);
|
||
|
return this;
|
||
|
},
|
||
|
year: function year() {
|
||
|
add('Y', 1970, 2450);
|
||
|
return this;
|
||
|
},
|
||
|
fullDate: function fullDate() {
|
||
|
for (var _i13 = 0, _values3 = values, length = _values3.length; _i13 < length; _i13++) {
|
||
|
values[_i13] = values[_i13].getTime();
|
||
|
}
|
||
|
add('fd');
|
||
|
return this;
|
||
|
},
|
||
|
customModifier: function customModifier(id, vals) {
|
||
|
var custom = later.modifier[id];
|
||
|
if (!custom) throw new Error('Custom modifier ' + id + ' not recognized!');
|
||
|
modifier = id;
|
||
|
values = Array.isArray(arguments[1]) ? arguments[1] : [arguments[1]];
|
||
|
return this;
|
||
|
},
|
||
|
customPeriod: function customPeriod(id) {
|
||
|
var custom = later[id];
|
||
|
if (!custom) throw new Error('Custom time period ' + id + ' not recognized!');
|
||
|
add(id, custom.extent(new Date())[0], custom.extent(new Date())[1]);
|
||
|
return this;
|
||
|
},
|
||
|
startingOn: function startingOn(start) {
|
||
|
return this.between(start, last.m);
|
||
|
},
|
||
|
between: function between(start, end) {
|
||
|
cur[last.n] = cur[last.n].splice(0, last.c);
|
||
|
_every = last.x;
|
||
|
add(last.n, start, end);
|
||
|
return this;
|
||
|
},
|
||
|
and: function and() {
|
||
|
cur = curArray[curArray.push({}) - 1];
|
||
|
return this;
|
||
|
},
|
||
|
except: function except() {
|
||
|
curArray = exceptions;
|
||
|
cur = null;
|
||
|
return this;
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
later.parse.text = function (string) {
|
||
|
var recur = later.parse.recur;
|
||
|
var pos = 0;
|
||
|
var input = '';
|
||
|
var error;
|
||
|
var TOKENTYPES = {
|
||
|
eof: /^$/,
|
||
|
rank: /^((\d+)(st|nd|rd|th)?)\b/,
|
||
|
time: /^(((0?[1-9]|1[0-2]):[0-5]\d(\s)?(am|pm))|((0?\d|1\d|2[0-3]):[0-5]\d))\b/,
|
||
|
dayName: /^((sun|mon|tue(s)?|wed(nes)?|thu(r(s)?)?|fri|sat(ur)?)(day)?)\b/,
|
||
|
monthName: /^(jan(uary)?|feb(ruary)?|ma((r(ch)?)?|y)|apr(il)?|ju(ly|ne)|aug(ust)?|oct(ober)?|(sept|nov|dec)(ember)?)\b/,
|
||
|
yearIndex: /^(\d{4})\b/,
|
||
|
every: /^every\b/,
|
||
|
after: /^after\b/,
|
||
|
before: /^before\b/,
|
||
|
second: /^(s|sec(ond)?(s)?)\b/,
|
||
|
minute: /^(m|min(ute)?(s)?)\b/,
|
||
|
hour: /^(h|hour(s)?)\b/,
|
||
|
day: /^(day(s)?( of the month)?)\b/,
|
||
|
dayInstance: /^day instance\b/,
|
||
|
dayOfWeek: /^day(s)? of the week\b/,
|
||
|
dayOfYear: /^day(s)? of the year\b/,
|
||
|
weekOfYear: /^week(s)?( of the year)?\b/,
|
||
|
weekOfMonth: /^week(s)? of the month\b/,
|
||
|
weekday: /^weekday\b/,
|
||
|
weekend: /^weekend\b/,
|
||
|
month: /^month(s)?\b/,
|
||
|
year: /^year(s)?\b/,
|
||
|
between: /^between (the)?\b/,
|
||
|
start: /^(start(ing)? (at|on( the)?)?)\b/,
|
||
|
at: /^(at|@)\b/,
|
||
|
and: /^(,|and\b)/,
|
||
|
except: /^(except\b)/,
|
||
|
also: /(also)\b/,
|
||
|
first: /^(first)\b/,
|
||
|
last: /^last\b/,
|
||
|
in: /^in\b/,
|
||
|
of: /^of\b/,
|
||
|
onthe: /^on the\b/,
|
||
|
on: /^on\b/,
|
||
|
through: /(-|^(to|through)\b)/
|
||
|
};
|
||
|
var NAMES = {
|
||
|
jan: 1,
|
||
|
feb: 2,
|
||
|
mar: 3,
|
||
|
apr: 4,
|
||
|
may: 5,
|
||
|
jun: 6,
|
||
|
jul: 7,
|
||
|
aug: 8,
|
||
|
sep: 9,
|
||
|
oct: 10,
|
||
|
nov: 11,
|
||
|
dec: 12,
|
||
|
sun: 1,
|
||
|
mon: 2,
|
||
|
tue: 3,
|
||
|
wed: 4,
|
||
|
thu: 5,
|
||
|
fri: 6,
|
||
|
sat: 7,
|
||
|
'1st': 1,
|
||
|
fir: 1,
|
||
|
'2nd': 2,
|
||
|
sec: 2,
|
||
|
'3rd': 3,
|
||
|
thi: 3,
|
||
|
'4th': 4,
|
||
|
for: 4
|
||
|
};
|
||
|
function t(start, end, text, type) {
|
||
|
return {
|
||
|
startPos: start,
|
||
|
endPos: end,
|
||
|
text: text,
|
||
|
type: type
|
||
|
};
|
||
|
}
|
||
|
function peek(expected) {
|
||
|
var scanTokens = Array.isArray(expected) ? expected : [expected];
|
||
|
var whiteSpace = /\s+/;
|
||
|
var token;
|
||
|
var curInput;
|
||
|
var m;
|
||
|
var scanToken;
|
||
|
var start;
|
||
|
var length_;
|
||
|
scanTokens.push(whiteSpace);
|
||
|
start = pos;
|
||
|
while (!token || token.type === whiteSpace) {
|
||
|
length_ = -1;
|
||
|
curInput = input.slice(Math.max(0, start));
|
||
|
token = t(start, start, input.split(whiteSpace)[0]);
|
||
|
var i;
|
||
|
var length = scanTokens.length;
|
||
|
for (i = 0; i < length; i++) {
|
||
|
scanToken = scanTokens[i];
|
||
|
m = scanToken.exec(curInput);
|
||
|
if (m && m.index === 0 && m[0].length > length_) {
|
||
|
length_ = m[0].length;
|
||
|
token = t(start, start + length_, curInput.slice(0, Math.max(0, length_)), scanToken);
|
||
|
}
|
||
|
}
|
||
|
if (token.type === whiteSpace) {
|
||
|
start = token.endPos;
|
||
|
}
|
||
|
}
|
||
|
return token;
|
||
|
}
|
||
|
function scan(expectedToken) {
|
||
|
var token = peek(expectedToken);
|
||
|
pos = token.endPos;
|
||
|
return token;
|
||
|
}
|
||
|
function parseThroughExpr(tokenType) {
|
||
|
var start = Number(parseTokenValue(tokenType));
|
||
|
var end = checkAndParse(TOKENTYPES.through) ? Number(parseTokenValue(tokenType)) : start;
|
||
|
var nums = [];
|
||
|
for (var i = start; i <= end; i++) {
|
||
|
nums.push(i);
|
||
|
}
|
||
|
return nums;
|
||
|
}
|
||
|
function parseRanges(tokenType) {
|
||
|
var nums = parseThroughExpr(tokenType);
|
||
|
while (checkAndParse(TOKENTYPES.and)) {
|
||
|
nums = nums.concat(parseThroughExpr(tokenType));
|
||
|
}
|
||
|
return nums;
|
||
|
}
|
||
|
function parseEvery(r) {
|
||
|
var number;
|
||
|
var period;
|
||
|
var start;
|
||
|
var end;
|
||
|
if (checkAndParse(TOKENTYPES.weekend)) {
|
||
|
r.on(NAMES.sun, NAMES.sat).dayOfWeek();
|
||
|
} else if (checkAndParse(TOKENTYPES.weekday)) {
|
||
|
r.on(NAMES.mon, NAMES.tue, NAMES.wed, NAMES.thu, NAMES.fri).dayOfWeek();
|
||
|
} else {
|
||
|
number = parseTokenValue(TOKENTYPES.rank);
|
||
|
r.every(number);
|
||
|
period = parseTimePeriod(r);
|
||
|
if (checkAndParse(TOKENTYPES.start)) {
|
||
|
number = parseTokenValue(TOKENTYPES.rank);
|
||
|
r.startingOn(number);
|
||
|
parseToken(period.type);
|
||
|
} else if (checkAndParse(TOKENTYPES.between)) {
|
||
|
start = parseTokenValue(TOKENTYPES.rank);
|
||
|
if (checkAndParse(TOKENTYPES.and)) {
|
||
|
end = parseTokenValue(TOKENTYPES.rank);
|
||
|
r.between(start, end);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function parseOnThe(r) {
|
||
|
if (checkAndParse(TOKENTYPES.first)) {
|
||
|
r.first();
|
||
|
} else if (checkAndParse(TOKENTYPES.last)) {
|
||
|
r.last();
|
||
|
} else {
|
||
|
r.on(parseRanges(TOKENTYPES.rank));
|
||
|
}
|
||
|
parseTimePeriod(r);
|
||
|
}
|
||
|
function parseScheduleExpr(string_) {
|
||
|
pos = 0;
|
||
|
input = string_;
|
||
|
error = -1;
|
||
|
var r = recur();
|
||
|
while (pos < input.length && error < 0) {
|
||
|
var token = parseToken([TOKENTYPES.every, TOKENTYPES.after, TOKENTYPES.before, TOKENTYPES.onthe, TOKENTYPES.on, TOKENTYPES.of, TOKENTYPES.in, TOKENTYPES.at, TOKENTYPES.and, TOKENTYPES.except, TOKENTYPES.also]);
|
||
|
switch (token.type) {
|
||
|
case TOKENTYPES.every:
|
||
|
parseEvery(r);
|
||
|
break;
|
||
|
case TOKENTYPES.after:
|
||
|
if (peek(TOKENTYPES.time).type !== undefined) {
|
||
|
r.after(parseTokenValue(TOKENTYPES.time));
|
||
|
r.time();
|
||
|
} else {
|
||
|
r.after(parseTokenValue(TOKENTYPES.rank));
|
||
|
parseTimePeriod(r);
|
||
|
}
|
||
|
break;
|
||
|
case TOKENTYPES.before:
|
||
|
if (peek(TOKENTYPES.time).type !== undefined) {
|
||
|
r.before(parseTokenValue(TOKENTYPES.time));
|
||
|
r.time();
|
||
|
} else {
|
||
|
r.before(parseTokenValue(TOKENTYPES.rank));
|
||
|
parseTimePeriod(r);
|
||
|
}
|
||
|
break;
|
||
|
case TOKENTYPES.onthe:
|
||
|
parseOnThe(r);
|
||
|
break;
|
||
|
case TOKENTYPES.on:
|
||
|
r.on(parseRanges(TOKENTYPES.dayName)).dayOfWeek();
|
||
|
break;
|
||
|
case TOKENTYPES.of:
|
||
|
r.on(parseRanges(TOKENTYPES.monthName)).month();
|
||
|
break;
|
||
|
case TOKENTYPES.in:
|
||
|
r.on(parseRanges(TOKENTYPES.yearIndex)).year();
|
||
|
break;
|
||
|
case TOKENTYPES.at:
|
||
|
r.on(parseTokenValue(TOKENTYPES.time)).time();
|
||
|
while (checkAndParse(TOKENTYPES.and)) {
|
||
|
r.on(parseTokenValue(TOKENTYPES.time)).time();
|
||
|
}
|
||
|
break;
|
||
|
case TOKENTYPES.and:
|
||
|
break;
|
||
|
case TOKENTYPES.also:
|
||
|
r.and();
|
||
|
break;
|
||
|
case TOKENTYPES.except:
|
||
|
r.except();
|
||
|
break;
|
||
|
default:
|
||
|
error = pos;
|
||
|
}
|
||
|
}
|
||
|
return {
|
||
|
schedules: r.schedules,
|
||
|
exceptions: r.exceptions,
|
||
|
error: error
|
||
|
};
|
||
|
}
|
||
|
function parseTimePeriod(r) {
|
||
|
var timePeriod = parseToken([TOKENTYPES.second, TOKENTYPES.minute, TOKENTYPES.hour, TOKENTYPES.dayOfYear, TOKENTYPES.dayOfWeek, TOKENTYPES.dayInstance, TOKENTYPES.day, TOKENTYPES.month, TOKENTYPES.year, TOKENTYPES.weekOfMonth, TOKENTYPES.weekOfYear]);
|
||
|
switch (timePeriod.type) {
|
||
|
case TOKENTYPES.second:
|
||
|
r.second();
|
||
|
break;
|
||
|
case TOKENTYPES.minute:
|
||
|
r.minute();
|
||
|
break;
|
||
|
case TOKENTYPES.hour:
|
||
|
r.hour();
|
||
|
break;
|
||
|
case TOKENTYPES.dayOfYear:
|
||
|
r.dayOfYear();
|
||
|
break;
|
||
|
case TOKENTYPES.dayOfWeek:
|
||
|
r.dayOfWeek();
|
||
|
break;
|
||
|
case TOKENTYPES.dayInstance:
|
||
|
r.dayOfWeekCount();
|
||
|
break;
|
||
|
case TOKENTYPES.day:
|
||
|
r.dayOfMonth();
|
||
|
break;
|
||
|
case TOKENTYPES.weekOfMonth:
|
||
|
r.weekOfMonth();
|
||
|
break;
|
||
|
case TOKENTYPES.weekOfYear:
|
||
|
r.weekOfYear();
|
||
|
break;
|
||
|
case TOKENTYPES.month:
|
||
|
r.month();
|
||
|
break;
|
||
|
case TOKENTYPES.year:
|
||
|
r.year();
|
||
|
break;
|
||
|
default:
|
||
|
error = pos;
|
||
|
}
|
||
|
return timePeriod;
|
||
|
}
|
||
|
function checkAndParse(tokenType) {
|
||
|
var found = peek(tokenType).type === tokenType;
|
||
|
if (found) {
|
||
|
scan(tokenType);
|
||
|
}
|
||
|
return found;
|
||
|
}
|
||
|
function parseToken(tokenType) {
|
||
|
var t = scan(tokenType);
|
||
|
if (t.type) {
|
||
|
t.text = convertString(t.text, tokenType);
|
||
|
} else {
|
||
|
error = pos;
|
||
|
}
|
||
|
return t;
|
||
|
}
|
||
|
function parseTokenValue(tokenType) {
|
||
|
return parseToken(tokenType).text;
|
||
|
}
|
||
|
function convertString(string_, tokenType) {
|
||
|
var output = string_;
|
||
|
switch (tokenType) {
|
||
|
case TOKENTYPES.time:
|
||
|
/*
|
||
|
const parts = string_.split(/(:|am|pm)/);
|
||
|
const hour =
|
||
|
parts[3] === 'pm' && parts[0] < 12
|
||
|
? Number.parseInt(parts[0], 10) + 12
|
||
|
: parts[0];
|
||
|
const min = parts[2].trim();
|
||
|
output = (hour.length === 1 ? '0' : '') + hour + ':' + min;
|
||
|
*/
|
||
|
// <https://github.com/bunkat/later/pull/188>
|
||
|
var parts = string_.split(/(:|am|pm)/);
|
||
|
var hour = Number.parseInt(parts[0], 10);
|
||
|
var min = parts[2].trim();
|
||
|
if (parts[3] === 'pm' && hour < 12) {
|
||
|
hour += 12;
|
||
|
} else if (parts[3] === 'am' && hour === 12) {
|
||
|
hour -= 12;
|
||
|
}
|
||
|
hour = String(hour);
|
||
|
output = (hour.length === 1 ? '0' : '') + hour + ':' + min;
|
||
|
break;
|
||
|
case TOKENTYPES.rank:
|
||
|
output = Number.parseInt(/^\d+/.exec(string_)[0], 10);
|
||
|
break;
|
||
|
case TOKENTYPES.monthName:
|
||
|
case TOKENTYPES.dayName:
|
||
|
output = NAMES[string_.slice(0, 3)];
|
||
|
break;
|
||
|
}
|
||
|
return output;
|
||
|
}
|
||
|
return parseScheduleExpr(string.toLowerCase());
|
||
|
};
|
||
|
function getOffset(date, zone) {
|
||
|
var d = date.toLocaleString('en-US', {
|
||
|
hour12: false,
|
||
|
timeZone: zone,
|
||
|
timeZoneName: 'short'
|
||
|
}) //=> ie. "8/22/2021, 24:30:00 EDT"
|
||
|
.match(/(\d+)\/(\d+)\/(\d+),? (\d+):(\d+):(\d+)/).map(function (n) {
|
||
|
return n.length === 1 ? '0' + n : n;
|
||
|
});
|
||
|
var zdate = new Date("".concat(d[3], "-").concat(d[1], "-").concat(d[2], "T").concat(d[4].replace('24', '00'), ":").concat(d[5], ":").concat(d[6], "Z"));
|
||
|
return date.getTime() - zdate.getTime();
|
||
|
} // getOffset()
|
||
|
|
||
|
module.exports = later;
|
||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJwa2ciLCJyZXF1aXJlIiwibGF0ZXIiLCJ2ZXJzaW9uIiwiYXJyYXkiLCJzb3J0IiwiemVyb0lzTGFzdCIsImEiLCJiIiwiTnVtYmVyIiwicHVzaCIsInNoaWZ0IiwibmV4dCIsInZhbHVlIiwidmFsdWVzIiwiZXh0ZW50IiwiY3VyIiwiemVyb0lzTGFyZ2VzdCIsIm5leHRJZHgiLCJpIiwibGVuZ3RoIiwibmV4dEludmFsaWQiLCJtaW4iLCJtYXgiLCJ6ZXJvVmFsdWUiLCJpbmRleE9mIiwic3RhcnQiLCJ1bmRlZmluZWQiLCJwcmV2IiwicHJldmlvdXNJZHgiLCJwcmV2SW52YWxpZCIsImRheSIsIkQiLCJuYW1lIiwicmFuZ2UiLCJ2YWwiLCJkIiwiZGF0ZSIsImdldERhdGUiLCJjYWxsIiwiaXNWYWxpZCIsIkRFeHRlbnQiLCJtb250aCIsIk0iLCJEQVlTX0lOX01PTlRIIiwiZHkiLCJEU3RhcnQiLCJZIiwiZW5kIiwiREVuZCIsIm5leHRSb2xsb3ZlciIsIkRNYXgiLCJwcmV2Um9sbG92ZXIiLCJkYXlPZldlZWtDb3VudCIsImRjIiwiTWF0aCIsImZsb29yIiwiZGNFeHRlbnQiLCJjZWlsIiwiZGNTdGFydCIsImRjRW5kIiwiZGNNYXgiLCJnZXRUaW1lIiwiZGF5T2ZXZWVrIiwiZHciLCJnZXREYXkiLCJkYXlPZlllYXIiLCJEQVkiLCJ5ZWFyIiwiZHlFeHRlbnQiLCJkeU1heCIsImhvdXIiLCJoIiwiZ2V0SG91ciIsImhTdGFydCIsImhFbmQiLCJpc1VUQyIsIm1pbnV0ZSIsIm0iLCJnZXRNaW4iLCJtU3RhcnQiLCJtRW5kIiwicyIsImluYyIsIkRhdGUiLCJNSU4iLCJTRUMiLCJnZXRNb250aCIsIk1TdGFydCIsIk1FbmQiLCJzZWNvbmQiLCJnZXRTZWMiLCJjYWNoZSIsInRpbWUiLCJ0Iiwid2Vla09mTW9udGgiLCJ3bSIsIndtRXh0ZW50Iiwid21TdGFydCIsIndtRW5kIiwid21NYXgiLCJ3ZWVrT2ZZZWFyIiwid3kiLCJ3VGh1ciIsIllUaHVyIiwiV0VFSyIsInd5RXh0ZW50IiwiZHdGaXJzdCIsImR3TGFzdCIsInd5U3RhcnQiLCJ3eUVuZCIsInd5VGh1ciIsInd5TWF4IiwiZ2V0WWVhciIsIllTdGFydCIsIllFbmQiLCJORVZFUiIsImZ1bGxEYXRlIiwiZmQiLCJtb2RpZmllciIsImFmdGVyIiwiY29uc3RyYWludCIsInZhbHVlXyIsInN0YXJ0RGF0ZSIsImJlZm9yZSIsImNvbXBpbGUiLCJzY2hlZERlZiIsImNvbnN0cmFpbnRzIiwiY29uc3RyYWludHNMZW5ndGgiLCJ0aWNrQ29uc3RyYWludCIsImtleSIsIm5hbWVQYXJ0cyIsInNwbGl0IiwibW9kIiwidmFscyIsInJhIiwicmIiLCJjb21wYXJlRm4iLCJkaXIiLCJuZXh0VmFsdWUiLCJtYXhBdHRlbXB0cyIsImRvbmUiLCJjdXJWYWx1ZSIsIm5ld1ZhbHVlIiwicmVzdWx0IiwiY29tcGFyZSIsInRpY2siLCJ0aWNrU3RhcnQiLCJzY2hlZHVsZSIsInNjaGVkIiwiRXJyb3IiLCJzY2hlZHVsZXMiLCJzY2hlZHVsZXNMZW5ndGgiLCJleGNlcHRpb25zIiwiZXhjZXB0aW9uc0xlbmd0aCIsImoiLCJnZXRJbnN0YW5jZXMiLCJjb3VudCIsImVuZERhdGUiLCJpc1JhbmdlIiwibG9vcENvdW50Iiwic2NoZWRTdGFydHMiLCJleGNlcHRTdGFydHMiLCJyZXN1bHRzIiwiaXNGb3J3YXJkIiwibGFzdFJlc3VsdCIsInJTdGFydCIsInJFbmQiLCJzZXROZXh0U3RhcnRzIiwic2V0UmFuZ2VTdGFydHMiLCJmaW5kTmV4dCIsInVwZGF0ZVJhbmdlU3RhcnRzIiwiY2FsY1JhbmdlT3ZlcmxhcCIsInVwZGF0ZU5leHRTdGFydHMiLCJtYXhFbmREYXRlIiwiY2FsY01heEVuZERhdGUiLCJjYWxjRW5kIiwiciIsImdldFN0YXJ0IiwidGlja1N0YXJ0cyIsIk9iamVjdCIsInByb3RvdHlwZSIsInRvU3RyaW5nIiwiY2xlYW5EYXRlIiwiaXNOYU4iLCJ2YWx1ZU9mIiwic2NoZWRBcnJheSIsInN0YXJ0c0FycmF5IiwicmFuZ2VzQXJyYXkiLCJuZXh0U3RhcnQiLCJtaW5FbmREYXRlIiwiZXhjZXB0c0FycmF5IiwibmV4dFJhbmdlIiwicHJldlJhbmdlIiwic2V0VGltZW91dCIsImZuIiwidGltZXpvbmUiLCJzY2hlZHVsZVRpbWVvdXQiLCJub3ciLCJpbmNsdWRlcyIsImxvY2FsT2Zmc2V0TWlsbGlzIiwiZ2V0VGltZXpvbmVPZmZzZXQiLCJvZmZzZXRNaWxsaXMiLCJnZXRPZmZzZXQiLCJhZGp1c3RlZE5vdyIsIm1hcCIsImRpZmYiLCJpc0RvbmUiLCJjbGVhciIsImNsZWFyVGltZW91dCIsInNldEludGVydmFsIiwidXNlTG9jYWxUaW1lIiwiYnVpbGQiLCJVVEMiLCJnZXQiLCJsb2NhbFRpbWUiLCJIT1VSIiwicGVyaW9kIiwiYXJndW1lbnRzIiwicGFyc2UiLCJjcm9uIiwiZXhwciIsImhhc1NlY29uZHMiLCJOQU1FUyIsIkpBTiIsIkZFQiIsIk1BUiIsIkFQUiIsIk1BWSIsIkpVTiIsIkpVTCIsIkFVRyIsIlNFUCIsIk9DVCIsIk5PViIsIkRFQyIsIlNVTiIsIk1PTiIsIlRVRSIsIldFRCIsIlRIVSIsIkZSSSIsIlNBVCIsIlJFUExBQ0VNRU5UUyIsIkZJRUxEUyIsImdldFZhbHVlIiwib2Zmc2V0IiwiY2xvbmVTY2hlZHVsZSIsImNsb25lIiwiZmllbGQiLCJzbGljZSIsImFkZCIsImFkZEhhc2giLCJjdXJTY2hlZCIsImhhc2giLCJhZGRXZWVrZGF5IiwiZXhjZXB0MSIsImV4Y2VwdDIiLCJhZGRSYW5nZSIsIml0ZW0iLCJpbmNTcGxpdCIsInJhbmdlU3BsaXQiLCJyZXBsYWNlIiwiaXNIYXNoIiwiaXRlbVNvcnRlciIsInBhcnNlRXhwciIsImNvbXBvbmVudHMiLCJmIiwiY29tcG9uZW50IiwiaXRlbXMiLCJfaXRlbXMiLCJwcmVwYXJlRXhwciIsInByZXBhcmVkIiwidG9VcHBlckNhc2UiLCJlIiwicmVjdXIiLCJjdXJBcnJheSIsImN1ck5hbWUiLCJldmVyeSIsImFwcGx5TWluIiwiYXBwbHlNYXgiLCJsYXN0IiwibiIsIngiLCJjIiwiX3ZhbHVlcyIsIm9uIiwiQXJyYXkiLCJpc0FycmF5IiwiZmlyc3QiLCJfdmFsdWVzMiIsImRheU9mTW9udGgiLCJvbldlZWtlbmQiLCJvbldlZWtkYXkiLCJfdmFsdWVzMyIsImN1c3RvbU1vZGlmaWVyIiwiaWQiLCJjdXN0b20iLCJjdXN0b21QZXJpb2QiLCJzdGFydGluZ09uIiwiYmV0d2VlbiIsInNwbGljZSIsImFuZCIsImV4Y2VwdCIsInRleHQiLCJzdHJpbmciLCJwb3MiLCJpbnB1dCIsImVycm9yIiwiVE9LRU5UWVBFUyIsImVvZiIsInJhbmsiLCJkYXlOYW1lIiwibW9udGhOYW1lIiwieWVhckluZGV4IiwiZGF5SW5zdGFuY2U
|