Security News
Introducing the Socket Python SDK
The initial version of the Socket Python SDK is now on PyPI, enabling developers to more easily interact with the Socket REST API in Python projects.
Trigger functions and/or evaluate cron expressions in JavaScript. No dependencies. Most features. All environmens.
The croner npm package is a high-performance task scheduler for Node.js that allows you to run tasks at specific times or intervals. It is designed to be a drop-in replacement for the 'cron' package with additional features and improvements.
Simple cron job scheduling
This feature allows you to schedule a task to run at intervals defined by the cron syntax. In the provided code sample, a job is scheduled to run every 5 seconds.
const { Cron } = require('croner');
const job = Cron('*/5 * * * * *', () => {
console.log('This will run every 5 seconds');
});
One-time execution
This feature allows you to schedule a task to run once at a specific time in the future. The code sample schedules a job to run once after 10 seconds.
const { Cron } = require('croner');
const job = Cron(new Date(Date.now() + 10000), () => {
console.log('This will run once after 10 seconds');
});
Stopping a job
This feature allows you to stop a scheduled job. In the code sample, a job is scheduled to run every 5 seconds but is stopped after 15 seconds.
const { Cron } = require('croner');
const job = Cron('*/5 * * * * *', () => {
console.log('This job will be stopped.');
});
setTimeout(() => {
job.stop();
}, 15000);
Timezone support
This feature allows you to schedule jobs according to a specific timezone. The code sample schedules a job to run at 10:30 AM in the 'America/New_York' timezone.
const { Cron } = require('croner');
const job = Cron('0 30 10 * * *', () => {
console.log('This will run at 10:30 AM in the America/New_York timezone.');
}, { timezone: 'America/New_York' });
node-schedule is a flexible cron-like and not-cron-like job scheduler for Node.js. It allows you to schedule jobs using both cron-style and human-readable syntax. It is similar to croner but offers a different API and additional scheduling features like scheduling jobs with JavaScript Date objects.
agenda is a job scheduling library for Node.js that uses MongoDB for persisting job data. It is more suitable for distributed or long-running job tasks. Unlike croner, which focuses on in-memory cron job scheduling, agenda provides persistence and is better suited for applications that require job recovery and failover capabilities.
bull is a Redis-based queue system for Node.js. It is designed for handling distributed jobs and messages in Node.js applications. While croner is used for scheduling tasks, bull is more focused on job queuing, processing, and concurrency, making it suitable for more complex job handling scenarios.
Trigger functions and/or evaluate cron expressions in JavaScript. No dependencies. Most features. Node. Deno. Browser.
Try it live on jsfiddle.
Quick examples:
// Basic: Run a function at the interval defined by a cron expression
const job = Cron('*/5 * * * * *', () => {
console.log('This will run every fifth second');
});
// Enumeration: What dates do the next 100 sundays occur at?
const nextSundays = Cron('0 0 0 * * 7').enumerate(100);
console.log(nextSundays);
// Days left to a specific date
const msLeft = Cron('59 59 23 24 DEC *').next() - new Date();
console.log(Math.floor(msLeft/1000/3600/24) + " days left to next christmas eve");
// Run a function at a specific date/time using a non-local timezone (time is ISO 8601 local time)
// This will run 2023-01-23 00:00:00 according to the time in Asia/Kolkata
Cron('2023-01-23T00:00:00', { timezone: 'Asia/Kolkata' }, () => { console.log('Yay') });
More examples...
Because the existing ones aren't good enough. They have serious bugs, use bloated dependencies, do not work in all environments and/or simply don't work as expected.
Benchmark at 2022-02-20:
> node cron-implementation-test.js
Test: When is 23:00 next 31st march, pattern '0 0 23 31 3 *'
node-schedule: 2022-03-31 23:00:00 in 15.379ms
node-cron: ??? in 0.339ms
Month '3' is limited to '30' days.
cron: 2022-04-01 23:00:00 in 7.785ms
croner (legacy): 2022-03-31 23:00:00 in 2.142ms
croner (default): 2022-03-31 23:00:00 in 0.672ms
Test: When is next 15th of february, pattern '0 0 0 15 2 *'
node-schedule: 2023-02-15 00:00:00 in 43.875ms
node-cron: ??? in 2.217ms
cron: 2022-03-15 00:00:00 in 4.147ms
croner (legacy): 2023-02-15 00:00:00 in 1.72ms
croner (default): 2023-02-15 00:00:00 in 0.946ms
Test: When is next monday in october, pattern '0 0 0 * 10 1'
node-schedule: 2022-10-03 00:00:00 in 5.594ms
node-cron: ??? in 3.62ms
cron: 2022-11-07 00:00:00 in 1.658ms
croner (legacy): 2022-10-03 00:00:00 in 0.697ms
croner (default): 2022-10-03 00:00:00 in 0.546ms
https://gist.github.com/Hexagon/703f85f2dd86443cc17eef8f5cc6cb70
npm install croner --save
JavaScript
// ESM Import ...
import Cron from "croner";
// ... or CommonJS Require
const Cron = require("croner");
TypeScript
Notes for TypeScript:
new-cap
combined with no-new
, you need to import and use lower case cron
instead of { Cron }
.import { Cron } from "croner";
const job : Cron = new Cron("* * * * * *", () => {
console.log("This will run every second.");
});
JavaScript
import Cron from "https://cdn.jsdelivr.net/gh/hexagon/croner@4/src/croner.js";
Cron("* * * * * *", () => {
console.log("This will run every second.");
});
TypeScript
import { Cron } from "https://cdn.jsdelivr.net/gh/hexagon/croner@4/src/croner.js";
const _scheduler : Cron = new Cron("* * * * * *", () => {
console.log("This will run every second.");
});
croner.min.js
(UMD and standalone) or croner.min.mjs
(ES-module) from the dist/ folderTo use as a UMD-module (stand alone, RequireJS etc.)
<script src="https://cdn.jsdelivr.net/npm/croner@4/dist/croner.min.js"></script>
To use as a ES-module
<script type="module">
import Cron from "https://cdn.jsdelivr.net/npm/croner@4/dist/croner.min.mjs";
// ... see usage section ...
</script>
Full documentation available at hexagon.github.io/croner.
The short version:
Cron takes three arguments
const job = Cron("* * * * * *" /* Or a date object, or ISO 8601 local time */ , /*optional*/ { maxRuns: 1 } , /*optional*/ () => {} );
// If function is omitted in constructor, it can be scheduled later
job.schedule((/* optional */ job, /* optional */ context) => {});
// States
const nextRun = job.next( /*optional*/ previousRun ); // Get a Date object representing next run
const nextRuns = job.enumerate(10, /*optional*/ startFrom ); // Get a array of Dates, containing next 10 runs according to pattern
const prevRun = job.previous( );
const msToNext = job.msToNext( /*optional*/ previousRun ); // Milliseconds left to next execution
const isRunning = job.running();
// Control scheduled execution
job.pause();
job.resume();
job.stop();
Key | Default value | Data type | Remarks |
---|---|---|---|
maxRuns | Infinite | Number | |
catch | false | Boolean | Catch and ignore unhandled errors in triggered function |
timezone | undefined | String | Timezone in Europe/Stockholm format |
startAt | undefined | String | ISO 8601 formatted datetime (2021-10-17T23:43:00) in local or specified timezone |
stopAt | undefined | String | ISO 8601 formatted datetime (2021-10-17T23:43:00) in local or specified timezone |
interval | 0 | Number | Minimum number of seconds between triggers. |
paused | false | Boolean | If the job should be paused from start. |
context | undefined | Any | Passed as the second parameter to triggered function |
legacyMode | false | boolean | Combine day-of-month and day-of-week using OR, default is AND |
The expressions of Croner are very similar to the ones of Vixie Cron, with a few additions and changes listed below.
In croner, a combination of day-of-week and day-of-month will only trigger when both conditions match. An example: 0 20 1 * MON
will only trigger when monday occur the first day of any month. In Vixie Cron, it would trigger every monday AND the first day of every month. Vixie style can be enabled with legacyMode: true
from version 4.2.0
. See issue #53 for more information.
Croner expressions support the following additional modifiers
? ? * * * *
would be substituted with 25 8 * * * *
if time is <any hour>:08:25
at the time of new Cron('? ? * * * *', <...>)
. The question mark can be used in any field.Croner also allow you to pass a javascript Date object, or a ISO 8601 formatted string, as a pattern. The scheduled function will trigger once at the specified date/time. If you use a timezone different from local, you pass ISO 8601 local time in target location, and specify timezone using the options (2nd parameter).
// ┌──────────────── (optional) second (0 - 59)
// │ ┌────────────── minute (0 - 59)
// │ │ ┌──────────── hour (0 - 23)
// │ │ │ ┌────────── day of month (1 - 31)
// │ │ │ │ ┌──────── month (1 - 12, JAN-DEC)
// │ │ │ │ │ ┌────── day of week (0 - 6, SUN-Mon)
// │ │ │ │ │ │ (0 to 6 are Sunday to Saturday; 7 is Sunday, the same as 0)
// │ │ │ │ │ │
// * * * * * *
Field | Required | Allowed values | Allowed special characters | Remarks |
---|---|---|---|---|
Seconds | Optional | 0-59 | * , - / ? | |
Minutes | Yes | 0-59 | * , - / ? | |
Hours | Yes | 0-23 | * , - / ? | |
Day of Month | Yes | 1-31 | * , - / ? L | |
Month | Yes | 1-12 or JAN-DEC | * , - / ? | |
Day of Week | Yes | 0-7 or SUN-MON | * , - / ? | 0 to 6 are Sunday to Saturday 7 is Sunday, the same as 0 |
Note: Weekday and month names are case insensitive. Both MON and mon works.
It is also possible to use the following "nicknames" as pattern.
Nickname | Description |
---|---|
@yearly | Run once a year, ie. "0 0 1 1 *". |
@annually | Run once a year, ie. "0 0 1 1 *". |
@monthly | Run once a month, ie. "0 0 1 * *". |
@weekly | Run once a week, ie. "0 0 * * 0". |
@daily | Run once a day, ie. "0 0 * * *". |
@hourly | Run once an hour, ie. "0 * * * *". |
// Run a function according to pattern
Cron('15-45/10 */5 1,2,3 ? JAN-MAR SAT', function () {
console.log('This will run every tenth second between second 15-45');
console.log('every fifth minute of hour 1,2 and 3 when day of month');
console.log('is the same as when Cron started, every saturday in January to March.');
});
// Trigger on specific interval combined with cron expression
Cron('* * * 7-16 * MON-FRI', { interval: 90 }, function () {
console.log('This will trigger every 90th second at 7-16 on mondays to fridays.');
});
// Find next month
const nextMonth = Cron("@monthly").next(),
nextSunday = Cron("@weekly").next(),
nextSat29feb = Cron("0 0 0 29 2 6").next(),
nextSunLastOfMonth = Cron("0 0 0 L * 7").next();
console.log("First day of next month: " + nextMonth.toLocaleDateString());
console.log("Next sunday: " + nextSunday.toLocaleDateString());
console.log("Next saturday at 29th of february: " + nextSat29feb.toLocaleDateString()); // 2048-02-29
console.log("Next month ending with a sunday: " + nextSunLastOfMonth.toLocaleDateString());
const job = Cron(
'* * * * *',
{
maxRuns: Infinity,
startAt: "2021-11-01T00:00:00",
stopAt: "2021-12-01T00:00:00",
timezone: "Europe/Stockholm"
},
function() {
console.log('This will run every minute, from 2021-11-01 to 2021-12-01 00:00:00');
}
);
const job = Cron('* * * * * *', (self) => {
console.log('This will run every second. Pause on second 10. Resume on 15. And quit on 20.');
console.log('Current second: ', new Date().getSeconds());
console.log('Previous run: ' + self.previous());
console.log('Next run: ' + self.next());
});
Cron('10 * * * * *', {maxRuns: 1}, () => job.pause());
Cron('15 * * * * *', {maxRuns: 1}, () => job.resume());
Cron('20 * * * * *', {maxRuns: 1}, () => job.stop());
const data = {
what: "stuff"
};
Cron('* * * * * *', { context: data }, (_self, context) => {
console.log('This will print stuff: ' + context.what);
});
Cron('*/5 * * * * *', { context: data }, (self, context) => {
console.log('After this, other stuff will be printed instead');
context.what = "other stuff";
self.stop();
});
// A javascript date, or a ISO 8601 local time string can be passed, to fire a function once.
// Always specify which timezone the ISO 8601 time string has with the timezone option.
let job = Cron("2025-01-01T23:00:00",{timezone: "Europe/Stockholm"},() => {
console.log('This will run at 2025-01-01 23:00:00 in timezone Europe/Stockholm');
});
if (job.next() === null) {
// The job will not fire for some reason
} else {
console.log("Job will fire at " + job.next());
}
// Start a job firing once each 5th second, run at most 3 times
const job = new Cron("0/5 * * * * *", { maxRuns: 3 }, (job) => {
// Do work
console.log('Job Running');
// Is this the last execution?
if (!job.next()) {
console.log('Last execution');
}
});
// Will there be no executions?
// This would trigger if you change maxRuns to 0, or manage to compose
// an impossible cron expression.
if (!job.next() && !job.previous()) {
console.log('No executions scheduled');
}
MIT
FAQs
Trigger functions and/or evaluate cron expressions in JavaScript. No dependencies. Most features. All environments.
The npm package croner receives a total of 1,072,772 weekly downloads. As such, croner popularity was classified as popular.
We found that croner demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The initial version of the Socket Python SDK is now on PyPI, enabling developers to more easily interact with the Socket REST API in Python projects.
Security News
Floating dependency ranges in npm can introduce instability and security risks into your project by allowing unverified or incompatible versions to be installed automatically, leading to unpredictable behavior and potential conflicts.
Security News
A new Rust RFC proposes "Trusted Publishing" for Crates.io, introducing short-lived access tokens via OIDC to improve security and reduce risks associated with long-lived API tokens.