cron-schedule
A zero-dependency cron parser and scheduler for Node.js, Deno and the browser.
Features
- Parse cron expressions.
- Get next or previous schedules from a specific starting date.
- Check if a date matches a cron expression.
- Schedule a function call based on a cron expression.
- Supports Node.js, Deno and the browser (IIFE or ESM, ES6 required)
- Lightweight and tree-shakeable.
Installation and usage
Node.js (CommonJS)
Via npm:
$ npm install cron-schedule
Via yarn:
$ yarn add cron-schedule
We test our code against the following Node.js releases (12.18
, 14.13
, 16.12
).
Other versions of node.js may also work, but this is not tested.
Usage
import { parseCronExpression } from 'cron-schedule'
const cron = parseCronExpression('*/5 * * * *')
console.log(cron.getNextDate(new Date(2020, 10, 20, 18, 32)))
Browser (IIFE)
<script src="https://unpkg.com/cron-schedule@:version"></script>
After the script has been loaded, you can use the global cronSchedule
object to access the API.
Usage
<script>
const cron = cronSchedule.parseCronExpression('*/5 * * * *')
console.log(cron.getNextDate(new Date(2020, 10, 20, 18, 32)))
</script>
Requires ES6 (ES2015) browser support. Internet Explorer is not supported. If you need to support older browsers, get cron-schedule via npm or yarn and transpile it with your bundler.
Browser (ECMAScript module)
<script type="module">
import { parseCronExpression } from 'https://cdn.skypack.dev/cron-schedule@:version'
const cron = parseCronExpression('*/5 * * * *')
console.log(cron.getNextDate(new Date(2020, 10, 20, 18, 32)))
</script>
Deno
import { parseCronExpression } from 'https://cdn.skypack.dev/cron-schedule@:version?dts'
const cron = parseCronExpression('*/5 * * * *')
console.log(cron.getNextDate(new Date(2020, 10, 20, 18, 32)))
Note on CDN usage
The examples above use unpkg for IIFE and Skypack for ESM.
The urls contain :version
placeholder. Replace :version
with the desired version. Semver ranges are supported. To always use the latest 2.x
version use ^2.0.0
.
See https://www.npmjs.com/package/cron-schedule for a list of available versions.
Work with cron expressions
import { parseCronExpression } from 'cron-schedule'
const cron = parseCronExpression('*/5 * * * *')
cron.getNextDate(startDate?: Date): Date
cron.getNextDates(amount: number, startDate?: Date): Date[]
cron.getNextDatesIterator(startDate: Date = new Date(), endDate?: Date): Generator<Date, undefined, undefined>
cron.getPrevDate(startDate: Date = new Date()): Date
cron.getPrevDates(amount: number, startDate?: Date): Date[]
cron.getPrevDatesIterator(startDate: Date = new Date(), endDate?: Date): Generator<Date, undefined, undefined>
cron.matchDate(date: Date): boolean
Schedule tasks based on cron expressions
You can schedule tasks to be executed based on a cron expression. cron-schedule comes with 2 different schedulers.
1. Timer based scheduler
The timer based cron scheduler creates one timer for every scheduled cron.
When the node timeout limit of ~24 days would be exceeded, it uses multiple consecutive timeouts.
import { TimerBasedCronScheduler as scheduler } from 'cron-schedule'
scheduler.setTimeout(cron: Cron, task: () => unknown, opts?: { errorHandler?: (err: Error) => unknown }): ITimerHandle
scheduler.setInterval(cron: Cron, task: () => unknown, opts?: { errorHandler?: (err: Error) => unknown }): ITimerHandle
scheduler.clearTimeoutOrInterval(handle: ITimerHandle): void
Pros:
- A task is scheduled exactly to the second of the next cron date.
Cons:
- There is one timer per task, which could lead to lower performance compared to the interval based scheduler if you have many scheduled tasks.
2. Interval based scheduler
The interval based scheduler checks for due task in a fixed interval. So there is only one interval for all tasks assigned to a scheduler.
You can have multiple instances of an interval based scheduler.
import { IntervalBasedCronScheduler } from 'cron-schedule'
const scheduler = new IntervalBasedCronScheduler(60 * 1000)
scheduler.registerTask(cron: Cron, task: () => unknown, opts?: { isOneTimeTask?: boolean, errorHandler?: (err: Error) => unknown }): number
scheduler.unregisterTask(id: number): void
scheduler.stop()
scheduler.start()
Pros:
- Only one interval for all tasks, which is quite performant.
Cons:
- Tasks are not executed exactly on the cron date.
- Tasks can only be executed once per interval.
For most people, the timer based scheduler should be a good option. When you have problems with long timeouts / intervals being skipped, or have performance problems because of many scheduled tasks, you should consider the interval based scheduler.
Cron expression format
cron_schedule uses the linux cron syntax as described here with the addition that you can optionally
specify seconds by prepending the minute field with another field.
┌───────────── second (0 - 59, optional)
│ ┌───────────── minute (0 - 59)
│ │ ┌───────────── hour (0 - 23)
│ │ │ ┌───────────── day of month (1 - 31)
│ │ │ │ ┌───────────── month (1 - 12)
│ │ │ │ │ ┌───────────── weekday (0 - 7)
* * * * * *
All linux cron features are supported, including
- lists
- ranges
- ranges in lists
- step values
- month names (jan,feb,... - case insensitive)
- weekday names (mon,tue,... - case insensitive)
- time nicknames (@yearly, @annually, @monthly, @weekly, @daily, @hourly - case insensitive)
For simple timing tasks like every x seconds, you should consider using setInterval
which is more suitable for simple timing tasks, as it does not have the calculation overhead.
Cron validation
Looking for a way to validate cron expressions in your backend (node.js) or in the browser with support for multiple presets? Check out cron-validate!
Use the npm-cron-schedule
preset to validate that cron expressions are supported by cron-schedule.