function CronParser() {}n/a
function _parseEntry(entry) {
var atoms = entry.split(' ');
if (atoms.length === 6) {
return {
interval: CronExpression.parse(entry)
};
} else if (atoms.length > 6) {
return {
interval: CronExpression.parse(entry),
command: atoms.slice(6, atoms.length)
};
} else {
throw new Error('Invalid entry: ' + entry);
}
}n/a
function CronDate(timestamp, tz) {
if (timestamp instanceof CronDate) {
timestamp = timestamp._date;
}
if (!tz) {
this._date = moment(timestamp);
} else {
this._date = moment.tz(timestamp, tz);
}
}...
this._date.subtract(1, 'second').startOf('second');
if (this.getTime() > prev) {
this._date.subtract(1, 'hour');
}
};
CronDate.prototype.getDate = function() {
return this._date.date();
};
CronDate.prototype.getFullYear = function() {
return this._date.year();
};
CronDate.prototype.getDay = function() {
...function CronExpression(fields, options) {
this._options = options;
this._tz = options.tz;
this._currentDate = new CronDate(options.currentDate, this._tz);
this._startDate = options.startDate ? new CronDate(options.startDate, this._tz) : null;
this._endDate = options.endDate ? new CronDate(options.endDate, this._tz) : null;
this._fields = {};
this._isIterator = options.iterator || false;
this._hasIterated = false;
this._utc = options.utc || false;
// Map fields
for (var i = 0, c = CronExpression.map.length; i < c; i++) {
var key = CronExpression.map[i];
this._fields[key] = fields[i];
}
}n/a
function parseExpression(expression, options, callback) {
return CronExpression.parse(expression, options, callback);
}...
Simple expression.
```javascript
var parser = require('cron-parser');
try {
var interval = parser.parseExpression('*/2 * * * *');
console.log('Date: ', interval.next().toString()); // Sat Dec 29 2012 00:42:00 GMT+0200 (EET)
console.log('Date: ', interval.next().toString()); // Sat Dec 29 2012 00:44:00 GMT+0200 (EET)
console.log('Date: ', interval.prev().toString()); // Sat Dec 29 2012 00:42:00 GMT+0200 (EET)
console.log('Date: ', interval.prev().toString()); // Sat Dec 29 2012 00:40:00 GMT+0200 (EET)
} catch (err) {
...function parseFile(filePath, callback) {
require('fs').readFile(filePath, function(err, data) {
if (err) {
callback(err);
return;
}
return callback(null, CronParser.parseString(data.toString()));
});
}n/a
function parseString(data) {
var self = this;
var blocks = data.split('\n');
var response = {
variables: {},
expressions: [],
errors: {}
};
for (var i = 0, c = blocks.length; i < c; i++) {
var block = blocks[i];
var matches = null;
var entry = block.replace(/^\s+|\s+$/g, ''); // Remove surrounding spaces
if (entry.length > 0) {
if (entry.match(/^#/)) { // Comment
continue;
} else if ((matches = entry.match(/^(.*)=(.*)$/))) { // Variable
response.variables[matches[1]] = matches[2];
} else { // Expression?
var result = null;
try {
result = self._parseEntry('0 ' + entry);
response.expressions.push(result.interval);
} catch (err) {
response.errors[entry] = err;
}
}
}
}
return response;
}n/a
function CronDate(timestamp, tz) {
if (timestamp instanceof CronDate) {
timestamp = timestamp._date;
}
if (!tz) {
this._date = moment(timestamp);
} else {
this._date = moment.tz(timestamp, tz);
}
}...
this._date.subtract(1, 'second').startOf('second');
if (this.getTime() > prev) {
this._date.subtract(1, 'hour');
}
};
CronDate.prototype.getDate = function() {
return this._date.date();
};
CronDate.prototype.getFullYear = function() {
return this._date.year();
};
CronDate.prototype.getDay = function() {
..._getUTC = function () {
return moment.utc(this._date);
}...
};
CronDate.prototype.getTime = function() {
return this._date.valueOf();
};
CronDate.prototype.getUTCDate = function() {
return this._getUTC().date();
};
CronDate.prototype.getUTCFullYear = function() {
return this._getUTC().year();
};
CronDate.prototype.getUTCDay = function() {
...addDay = function () {
this._date.add(1, 'day').startOf('day');
}n/a
addHour = function () {
var prev = this.getTime();
this._date.add(1, 'hour').startOf('hour');
if (this.getTime() <= prev) {
this._date.add(1, 'hour');
}
}n/a
addMinute = function () {
var prev = this.getTime();
this._date.add(1, 'minute').startOf('minute');
if (this.getTime() < prev) {
this._date.add(1, 'hour');
}
}n/a
addMonth = function () {
this._date.add(1, 'month').startOf('month');
}n/a
addSecond = function () {
var prev = this.getTime();
this._date.add(1, 'second').startOf('second');
if (this.getTime() < prev) {
this._date.add(1, 'hour');
}
}n/a
addYear = function () {
this._date.add(1, 'year');
}n/a
getDate = function () {
return this._date.date();
}n/a
getDay = function () {
return this._date.day();
}n/a
getFullYear = function () {
return this._date.year();
}n/a
getHours = function () {
return this._date.hours();
}...
return +val;
}
return parseSequence(value);
};
CronExpression.prototype._applyTimezoneShift = function(currentDate, method) {
var previousHour = currentDate.getHours();
currentDate[method]();
var currentHour = currentDate.getHours();
var diff = currentHour - previousHour;
if (diff === 2) {
// Starting DST
if (this._fields.hour.length !== 24) {
// Hour is specified
...getMinutes = function () {
return this._date.minute();
}...
if (diff === 2) {
// Starting DST
if (this._fields.hour.length !== 24) {
// Hour is specified
this._dstStart = currentHour;
}
} else if ((diff === 0) &&
(currentDate.getMinutes() === 0) &&
(currentDate.getSeconds() === 0)) {
// Ending DST
if (this._fields.hour.length !== 24) {
// Hour is specified
this._dstEnd = currentHour;
}
}
...getMonth = function () {
return this._date.month();
}n/a
getSeconds = function () {
return this._date.second();
}...
// Starting DST
if (this._fields.hour.length !== 24) {
// Hour is specified
this._dstStart = currentHour;
}
} else if ((diff === 0) &&
(currentDate.getMinutes() === 0) &&
(currentDate.getSeconds() === 0)) {
// Ending DST
if (this._fields.hour.length !== 24) {
// Hour is specified
this._dstEnd = currentHour;
}
}
};
...getTime = function () {
return this._date.valueOf();
}...
};
CronDate.prototype.addDay = function() {
this._date.add(1, 'day').startOf('day');
};
CronDate.prototype.addHour = function() {
var prev = this.getTime();
this._date.add(1, 'hour').startOf('hour');
if (this.getTime() <= prev) {
this._date.add(1, 'hour');
}
};
CronDate.prototype.addMinute = function() {
...getUTCDate = function () {
return this._getUTC().date();
}n/a
getUTCDay = function () {
return this._getUTC().day();
}n/a
getUTCFullYear = function () {
return this._getUTC().year();
}n/a
getUTCHours = function () {
return this._getUTC().hours();
}n/a
getUTCMinutes = function () {
return this._getUTC().minute();
}n/a
getUTCMonth = function () {
return this._getUTC().month();
}n/a
getUTCSeconds = function () {
return this._getUTC().second();
}n/a
setDate = function (d) {
return this._date.date(d);
}n/a
setDay = function (d) {
return this._date.day(d);
}n/a
setFullYear = function (y) {
return this._date.year(y);
}n/a
setHours = function (h) {
return this._date.hour(h);
}n/a
setMinutes = function (m) {
return this._date.minute(m);
}n/a
setMonth = function (m) {
return this._date.month(m);
}n/a
setSeconds = function (s) {
return this._date.second(s);
}n/a
subtractDay = function () {
this._date.subtract(1, 'day').endOf('day');
}n/a
subtractHour = function () {
var prev = this.getTime();
this._date.subtract(1, 'hour').endOf('hour');
if (this.getTime() >= prev) {
this._date.subtract(1, 'hour');
}
}n/a
subtractMinute = function () {
var prev = this.getTime();
this._date.subtract(1, 'minute').endOf('minute');
if (this.getTime() > prev) {
this._date.subtract(1, 'hour');
}
}n/a
subtractMonth = function () {
this._date.subtract(1, 'month').endOf('month');
}n/a
subtractSecond = function () {
var prev = this.getTime();
this._date.subtract(1, 'second').startOf('second');
if (this.getTime() > prev) {
this._date.subtract(1, 'hour');
}
}n/a
subtractYear = function () {
this._date.subtract(1, 'year');
}n/a
toDate = function () {
return this._date.toDate();
}...
};
CronDate.prototype.toString = function() {
return this._date.toString();
};
CronDate.prototype.toDate = function() {
return this._date.toDate();
};
function CronDate (timestamp, tz) {
if (timestamp instanceof CronDate) {
timestamp = timestamp._date;
}
...toISOString = function () {
return this._date.toISOString();
}...
};
CronDate.prototype.getUTCSeconds = function() {
return this._getUTC().second();
};
CronDate.prototype.toISOString = function() {
return this._date.toISOString();
};
CronDate.prototype.toJSON = function() {
return this._date.toJSON();
};
CronDate.prototype.setDate = function(d) {
...toJSON = function () {
return this._date.toJSON();
}...
};
CronDate.prototype.toISOString = function() {
return this._date.toISOString();
};
CronDate.prototype.toJSON = function() {
return this._date.toJSON();
};
CronDate.prototype.setDate = function(d) {
return this._date.date(d);
};
CronDate.prototype.setFullYear = function(y) {
...toString = function () {
return this._date.toString();
}...
```javascript
var parser = require('cron-parser');
try {
var interval = parser.parseExpression('*/2 * * * *');
console.log('Date: ', interval.next().toString()); // Sat Dec 29 2012 00:
42:00 GMT+0200 (EET)
console.log('Date: ', interval.next().toString()); // Sat Dec 29 2012 00:44:00 GMT+0200 (EET)
console.log('Date: ', interval.prev().toString()); // Sat Dec 29 2012 00:42:00 GMT+0200 (EET)
console.log('Date: ', interval.prev().toString()); // Sat Dec 29 2012 00:40:00 GMT+0200 (EET)
} catch (err) {
console.log('Error: ' + err.message);
}
...function CronExpression(fields, options) {
this._options = options;
this._tz = options.tz;
this._currentDate = new CronDate(options.currentDate, this._tz);
this._startDate = options.startDate ? new CronDate(options.startDate, this._tz) : null;
this._endDate = options.endDate ? new CronDate(options.endDate, this._tz) : null;
this._fields = {};
this._isIterator = options.iterator || false;
this._hasIterated = false;
this._utc = options.utc || false;
// Map fields
for (var i = 0, c = CronExpression.map.length; i < c; i++) {
var key = CronExpression.map[i];
this._fields[key] = fields[i];
}
}n/a
function _parseField(field, value, constraints) {
// Replace aliases
switch (field) {
case 'month':
case 'dayOfWeek':
var aliases = CronExpression.aliases[field];
value = value.replace(/[a-z]{1,3}/gi, function(match) {
match = match.toLowerCase();
if (typeof aliases[match] !== undefined) {
return aliases[match];
} else {
throw new Error('Cannot resolve alias "' + match + '"')
}
});
break;
}
// Check for valid characters.
if (!(/^[\d|/|*|\-|,]+$/.test(value))) {
throw new Error('Invalid characters, got value: ' + value)
}
// Replace '*'
if (value.indexOf('*') !== -1) {
value = value.replace(/\*/g, constraints.join('-'));
}
//
// Inline parsing functions
//
// Parser path:
// - parseSequence
// - parseRepeat
// - parseRange
/**
* Parse sequence
*
* @param {String} val
* @return {Array}
* @private
*/
function parseSequence (val) {
var stack = [];
function handleResult (result) {
var max = stack.length > 0 ? Math.max.apply(Math, stack) : -1;
if (result instanceof Array) { // Make sequence linear
for (var i = 0, c = result.length; i < c; i++) {
var value = result[i];
// Check constraints
if (value < constraints[0] || value > constraints[1]) {
throw new Error(
'Constraint error, got value ' + value + ' expected range ' +
constraints[0] + '-' + constraints[1]
);
}
if (value > max) {
stack.push(value);
}
max = Math.max.apply(Math, stack);
}
} else { // Scalar value
result = +result;
// Check constraints
if (result < constraints[0] || result > constraints[1]) {
throw new Error(
'Constraint error, got value ' + result + ' expected range ' +
constraints[0] + '-' + constraints[1]
);
}
if (field == 'dayOfWeek') {
result = result % 7;
}
stack.push(result);
}
}
var atoms = val.split(',');
if (atoms.length > 1) {
if (field !== 'dayOfWeek') {
var pattern = /\D/g;
atoms.sort(function (a, b) {
return parseInt(a.replace(pattern, ''), 10) - parseInt(b.replace(pattern, ''), 10);
});
}
for (var i = 0, c = atoms.length; i < c; i++) {
handleResult(parseRepeat(atoms[i]));
}
} else {
handleResult(parseRepeat(val));
}
return stack;
}
/**
* Parse repetition interval
*
* @param {String} val
* @return {Array}
*/
function parseRepeat (val) {
var repeatInterval = 1;
var atoms = val.split('/');
if (atoms.length > 1) {
return parseRange(atoms[0], atoms[atoms.length - 1]);
}
return parseRange(val, repeatInterval);
}
/**
* Parse range
*
* @param {String} val
* @param {Number} repeatInterval Repetition interval
* @return {Array}
* @private
*/
function parseRange (val, repeatInterval) {
var stack = [];
var atoms = val.split('-');
if (atoms.length > 1 ) {
// Invalid range, return value
if (atoms.length < 2 || !atoms[0].length) {
return +val;
}
// Validate range
var min = +atoms[0];
var max = +atoms[1];
if (safeIsNaN(min) || safeIsNaN(max) ||
min < constraints[0] || max > constraints[1]) {
throw new Error(
'Constraint error, got range ' +
min + '-' + max +
' expected range ' +
constraints[0] + '-' + constraints[1]
);
} else if (min >= max) {
throw new Error('Invalid range: ' + val);
}
// Create range
var repeatIndex = +repeatInterval;
if (safeIsNaN(repeatIndex) || repeatIndex <= 0) {
throw new Error('Constraint error, cannot repeat at every ' + repeatIndex + ' time.');
}
for (var index = min, count = max; index <= count; index++) {
if ......
// Resolve fields
var start = (CronExpression.map.length - atoms.length);
for (var i = 0, c = CronExpression.map.length; i < c; ++i) {
var field = CronExpression.map[i]; // Field name
var value = atoms[atoms.length > c ? i : i - start]; // Field value
if (i < start || !value) {
fields.push(CronExpression._parseField(
field,
CronExpression.parseDefaults[i],
CronExpression.constraints[i])
);
} else { // Use default value
fields.push(CronExpression._parseField(
field,
...function parse(expression, options, callback) {
var self = this;
if (typeof options === 'function') {
callback = options;
options = {};
}
function parse (expression, options) {
if (!options) {
options = {};
}
if (typeof options.currentDate === 'undefined') {
options.currentDate = new CronDate(undefined, self._tz);
}
// Is input expression predefined?
if (CronExpression.predefined[expression]) {
expression = CronExpression.predefined[expression];
}
// Split fields
var fields = [];
var atoms = (expression + '').trim().split(/\s+/);
// Resolve fields
var start = (CronExpression.map.length - atoms.length);
for (var i = 0, c = CronExpression.map.length; i < c; ++i) {
var field = CronExpression.map[i]; // Field name
var value = atoms[atoms.length > c ? i : i - start]; // Field value
if (i < start || !value) {
fields.push(CronExpression._parseField(
field,
CronExpression.parseDefaults[i],
CronExpression.constraints[i])
);
} else { // Use default value
fields.push(CronExpression._parseField(
field,
value,
CronExpression.constraints[i])
);
}
}
return new CronExpression(fields, options);
}
return parse(expression, options);
}...
var options = {
currentDate: '2016-03-27 00:00:01',
tz: 'Europe/Athens'
};
try {
var interval = CronExpression.parse('0 * * * *', options);
console.log('Date: ', interval.next().toString()); // Date: Sun Mar 27 2016 01:00:00 GMT+0200
console.log('Date: ', interval.next().toString()); // Date: Sun Mar 27 2016 02:00:00 GMT+0200
console.log('Date: ', interval.next().toString()); // Date: Sun Mar 27 2016 04:00:00 GMT+0300 (Notice DST transition
)
} catch (err) {
console.log('Error: ' + err.message);
}
..._applyTimezoneShift = function (currentDate, method) {
var previousHour = currentDate.getHours();
currentDate[method]();
var currentHour = currentDate.getHours();
var diff = currentHour - previousHour;
if (diff === 2) {
// Starting DST
if (this._fields.hour.length !== 24) {
// Hour is specified
this._dstStart = currentHour;
}
} else if ((diff === 0) &&
(currentDate.getMinutes() === 0) &&
(currentDate.getSeconds() === 0)) {
// Ending DST
if (this._fields.hour.length !== 24) {
// Hour is specified
this._dstEnd = currentHour;
}
}
}...
continue;
}
// Match hour
if (!matchSchedule(currentHour, this._fields.hour)) {
if (this._dstStart !== currentHour) {
this._dstStart = null;
this._applyTimezoneShift(currentDate, dateMathVerb + 'Hour');
continue;
} else if (!matchSchedule(currentHour - 1, this._fields.hour)) {
currentDate[dateMathVerb + 'Hour']();
continue;
}
} else if (this._dstEnd === currentHour) {
if (!reverse) {
...function _findSchedule(reverse) {
/**
* Match field value
*
* @param {String} value
* @param {Array} sequence
* @return {Boolean}
* @private
*/
function matchSchedule (value, sequence) {
for (var i = 0, c = sequence.length; i < c; i++) {
if (sequence[i] >= value) {
return sequence[i] === value;
}
}
return sequence[0] === value;
}
/**
* Detect if input range fully matches constraint bounds
* @param {Array} range Input range
* @param {Array} constraints Input constraints
* @returns {Boolean}
* @private
*/
function isWildcardRange (range, constraints) {
if (range instanceof Array && !range.length) {
return false;
}
if (constraints.length !== 2) {
return false;
}
return range.length === (constraints[1] - (constraints[0] < 1 ? - 1 : 0));
}
// Whether to use backwards directionality when searching
reverse = reverse || false;
var dateMathVerb = reverse ? 'subtract' : 'add';
var method = function(name) {
return !this._utc ? name : ('getUTC' + name.slice(3));
}.bind(this);
var currentDate = new CronDate(this._currentDate, this._tz);
var startDate = this._startDate;
var endDate = this._endDate;
// Find matching schedule
var initial_ts = currentDate.getTime();
while (true) {
// Validate timespan
if (reverse) {
if (startDate && (currentDate.getTime() - startDate.getTime() < 0)) {
throw new Error('Out of the timespan range');
}
} else {
if (endDate && (endDate.getTime() - currentDate.getTime()) < 0) {
throw new Error('Out of the timespan range');
}
}
// Day of month and week matching:
//
// "The day of a command's execution can be specified by two fields --
// day of month, and day of week. If both fields are restricted (ie,
// aren't *), the command will be run when either field matches the cur-
// rent time. For example, "30 4 1,15 * 5" would cause a command to be
// run at 4:30 am on the 1st and 15th of each month, plus every Friday."
//
// http://unixhelp.ed.ac.uk/CGI/man-cgi?crontab+5
//
var dayOfMonthMatch = matchSchedule(currentDate[method('getDate')](), this._fields.dayOfMonth);
var dayOfWeekMatch = matchSchedule(currentDate[method('getDay')](), this._fields.dayOfWeek);
var isDayOfMonthWildcardMatch = isWildcardRange(this._fields.dayOfMonth, CronExpression.constraints[3]);
var isMonthWildcardMatch = isWildcardRange(this._fields.month, CronExpression.constraints[4]);
var isDayOfWeekWildcardMatch = isWildcardRange(this._fields.dayOfWeek, CronExpression.constraints[5]);
var currentHour = currentDate[method('getHours')]();
// Validate days in month if explicit value is given
if (!isMonthWildcardMatch) {
var currentYear = currentDate[method('getFullYear')]();
var currentMonth = currentDate[method('getMonth')]() + 1;
var previousMonth = currentMonth === 1 ? 11 : currentMonth - 1;
var daysInPreviousMonth = CronExpression.daysInMonth[previousMonth - 1];
var daysOfMontRangeMax = this._fields.dayOfMonth[this._fields.dayOfMonth.length - 1];
var _daysInPreviousMonth = daysInPreviousMonth;
var _daysOfMontRangeMax = daysOfMontRangeMax;
// Handle leap year
var isLeap = !((currentYear % 4) || (!(currentYear % 100) && (currentYear % 400)));
if (isLeap) {
_daysInPreviousMonth = 29;
_daysOfMontRangeMax = 29;
}
if (this._fields.month[0] === previousMonth && _daysInPreviousMonth < _daysOfMontRangeMax) {
throw new Error('Invalid explicit day of month definition');
}
}
// Add or subtract day if select day not match with month (according to calendar)
if (!dayOfMonthMatch && !dayOfWeekMatch) {
currentDate[dateMathVerb + 'Day']();
continue;
}
// Add or subtract day if not day of month is set (and no match) and day of week is wildcard
if (!isDayOfMonthWildcardMatch && isDayOfWeekWildcardMatch && !dayOfMonthMatch) {
cur ......
/**
* Find next suitable date
*
* @public
* @return {CronDate|Object}
*/
CronExpression.prototype.next = function next () {
var schedule = this._findSchedule();
// Try to return ES6 compatible iterator
if (this._isIterator) {
return {
value: schedule,
done: !this.hasNext()
};
...hasNext = function () {
var current = this._currentDate;
var hasIterated = this._hasIterated;
try {
this._findSchedule();
return true;
} catch (err) {
return false;
} finally {
this._currentDate = current;
this._hasIterated = hasIterated;
}
}...
CronExpression.prototype.next = function next () {
var schedule = this._findSchedule();
// Try to return ES6 compatible iterator
if (this._isIterator) {
return {
value: schedule,
done: !this.hasNext()
};
}
return schedule;
};
/**
...hasPrev = function () {
var current = this._currentDate;
var hasIterated = this._hasIterated;
try {
this._findSchedule(true);
return true;
} catch (err) {
return false;
} finally {
this._currentDate = current;
this._hasIterated = hasIterated;
}
}...
CronExpression.prototype.prev = function prev () {
var schedule = this._findSchedule(true);
// Try to return ES6 compatible iterator
if (this._isIterator) {
return {
value: schedule,
done: !this.hasPrev()
};
}
return schedule;
};
/**
...function iterate(steps, callback) {
var dates = [];
if (steps >= 0) {
for (var i = 0, c = steps; i < c; i++) {
try {
var item = this.next();
dates.push(item);
// Fire the callback
if (callback) {
callback(item, i);
}
} catch (err) {
break;
}
}
} else {
for (var i = 0, c = steps; i > c; i--) {
try {
var item = this.prev();
dates.push(item);
// Fire the callback
if (callback) {
callback(item, i);
}
} catch (err) {
break;
}
}
}
return dates;
}n/a
function next() {
var schedule = this._findSchedule();
// Try to return ES6 compatible iterator
if (this._isIterator) {
return {
value: schedule,
done: !this.hasNext()
};
}
return schedule;
}...
```javascript
var parser = require('cron-parser');
try {
var interval = parser.parseExpression('*/2 * * * *');
console.log('Date: ', interval.next().toString()); // Sat Dec 29 2012 00:
42:00 GMT+0200 (EET)
console.log('Date: ', interval.next().toString()); // Sat Dec 29 2012 00:44:00 GMT+0200 (EET)
console.log('Date: ', interval.prev().toString()); // Sat Dec 29 2012 00:42:00 GMT+0200 (EET)
console.log('Date: ', interval.prev().toString()); // Sat Dec 29 2012 00:40:00 GMT+0200 (EET)
} catch (err) {
console.log('Error: ' + err.message);
}
...function prev() {
var schedule = this._findSchedule(true);
// Try to return ES6 compatible iterator
if (this._isIterator) {
return {
value: schedule,
done: !this.hasPrev()
};
}
return schedule;
}...
try {
var interval = parser.parseExpression('*/2 * * * *');
console.log('Date: ', interval.next().toString()); // Sat Dec 29 2012 00:42:00 GMT+0200 (EET)
console.log('Date: ', interval.next().toString()); // Sat Dec 29 2012 00:44:00 GMT+0200 (EET)
console.log('Date: ', interval.prev().toString()); // Sat Dec 29 2012 00:
42:00 GMT+0200 (EET)
console.log('Date: ', interval.prev().toString()); // Sat Dec 29 2012 00:40:00 GMT+0200 (EET)
} catch (err) {
console.log('Error: ' + err.message);
}
```
...function reset() {
this._currentDate = new CronDate(this._options.currentDate);
}n/a