Skip to content

Commit

Permalink
accept 'now' as a time spec, especially useful for one-shot jobs
Browse files Browse the repository at this point in the history
  • Loading branch information
andrasq committed Mar 27, 2019
1 parent 12fc351 commit 2296f2b
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 6 deletions.
6 changes: 6 additions & 0 deletions README.md
Expand Up @@ -30,6 +30,11 @@ minutes. The units must be one of 'd', 'h', 'm', or 's': days, hours, minutes,
Numbers can be integers or simple decimals with a decimal point, (eg "1.5h" 90 minutes).
Numbers without units are milliseconds, i.e. "1s 500" is 1500 ms.

Jobs scheduled for a time offset not less than the milliseconds since 1/1/70 GMT will
be scheduled to launch at the specified absolute runtime. As a convenience, the special
keyword `now` is recognized in timespecs as meaning the current datetime. `now` is
additive like the other time formats, so "now 20s" is 20 seconds from now.

To pass call arguments or an object instance to a method call, use the `options` form of the
call; see below.

Expand Down Expand Up @@ -111,6 +116,7 @@ for the same time the following day instead of letting them expire unrun.
Changelog
---------

- 0.5.0 - accept 'now' as a time spec, eg `at: 'now 10s'`
- 0.4.0 - job pause/resume methods, fix timespec units in options object
- 0.3.0 - allow units in timespec eg '2h 15m'
- 0.2.0 - first release
8 changes: 5 additions & 3 deletions cron.js
Expand Up @@ -81,6 +81,7 @@ Cron.prototype.setTimeout = function setTimeout( func, ms, repeat ) {

// given ms after midnight and ms between runs, find the next scheduled runtime in GMT
Cron.prototype._findNextRuntime = function _findNextRuntime( nowDate, offset, interval ) {
if (offset >= nowDate) return offset;
var midnight = nowDate - nowDate % Cron.msPerDay;
var next = midnight + offset;
if (!(interval > 0)) interval = Cron.msPerDay; // pretend daily if missing
Expand All @@ -102,11 +103,12 @@ function parseMs( ms ) {
if (typeof ms !== 'string') return ms;

var at = 0, match;
while ((match = /((\s*[.]\d+|\s*\d+[.]\d*|\s*\d+)\s*([dhms]|))/g.exec(ms))) {
while ((match = /(\s*(now|[.]\d+|\d+[.]\d*|\d+)\s*([dhms]|))/g.exec(ms))) {
ms = ms.slice(match[1].length);
at += +match[2] * unitScale[match[3]];
if (match[2] === 'now') at += new Date().getTime();
else at += +match[2] * unitScale[match[3]];
}
if (ms.length > 0) throw new Error(ms + ': bad time format, expected number[dhms]');
if (ms.trim().length > 0) throw new Error(ms + ': bad time format, expected number[dhms]');

return at;
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "qcron",
"version": "0.4.0",
"version": "0.5.0",
"description": "simple little call scheduler",
"main": "cron.js",
"license": "Apache-2.0",
Expand Down
8 changes: 6 additions & 2 deletions test.js
Expand Up @@ -47,14 +47,18 @@ module.exports = {
job = cron.scheduleCall(noop, 0, '1000');
t.equal(job._repeat, 1000);
t.equal(cron.scheduleCall(noop, 0, '2h')._repeat, 7200000);
t.equal(cron.scheduleCall(noop, 0, '3m')._repeat, 180000);
t.equal(cron.scheduleCall(noop, 0, '4s')._repeat, 4000);
t.equal(cron.scheduleCall(noop, 0, ' 3m')._repeat, 180000);
t.equal(cron.scheduleCall(noop, 0, ' 4 s ')._repeat, 4000);
t.equal(cron.scheduleCall(noop, 0, '4.5s')._repeat, 4500);
t.equal(cron.scheduleCall(noop, 0, '.5s 4000')._repeat, 4500);
t.equal(cron.scheduleCall(noop, 0, '4.5s 100')._repeat, 4600);
t.equal(cron.scheduleCall(noop, 0, '1d 2 h 3m4s5')._repeat, 93784005);
t.equal(cron.scheduleCall({ func: noop, at: 0, repeat: '2h' })._repeat, 7200000);
t.ok(cron.scheduleCall({ func: noop, at: 0, repeat: '2h' })._start > 0);
t.equal(cron.scheduleCall({ func: noop, at: '.05s now' })._start, 50 + new Date().getTime());
var now = Date.now();
t.throws(function() { cron.scheduleCall(noop, 'x') }, /expected number/);
t.throws(function() { cron.scheduleCall(noop, '3s new') }, /bad time format/);
t.done();
},

Expand Down

0 comments on commit 2296f2b

Please sign in to comment.