kelektiv / node-cron

Cron for NodeJS.
MIT License
8.3k stars 617 forks source link

Cron not working on the correct date #824

Closed cskiwi closed 5 months ago

cskiwi commented 6 months ago

Description

I want to trigger a method every first monday of the month. (this can be configured that it is every x months)

So for doing this, i had to use the following cron: 0 0 */31,1-7 */1 MON Looking at: https://elmah.io/tools/cron-parser/#0_0_*/31,1-7_*/1_1 this works as expected

Expected Behavior

Next date to be: Mon Jan 01 2024 01:00:00 GMT+0100

Actual Behavior

Date is the next monday (not first monday of the year): 2023-12-25T00:00:00.000+01:00

Possible Fix

No response

Steps to Reproduce

Link to stackbllitz

import * as cron from 'cron';

const dt = cron.sendAt('0 0 */31,1-7 */1 MON');
console.log(`The job would run at ...: ${dt.toISO()}`);

Context

The current date is: 22 december

Your Environment

Hexagon commented 6 months ago

I'm not a maintainer of this library, but let's break this down:

Part Expression Interpreted as ...
Minutes 0 at minute 00
Hours 0 at hour 00
Day of month */31,1-7 Every 31st day, starting from and including the 1st in every month and also day 1-7. Essentially days 1,2,3,4,5,6,7 (and 32 if it would have been a match).
Month */1 Every month, the same as a simple *
Day of week MON At mondays

As cron expressions do not combine the day of the month and the day of the week, any match in either of these fields would make a match. In this case, Mondays AND 1st, 2nd, 3rd, 4th, 5th, 6th, 7th. So the correct series of matches from today (2023-12-24) would be:

2023-12-25 00:00:00
2024-01-01 00:00:00
2024-01-02 00:00:00
2024-01-03 00:00:00
2024-01-04 00:00:00
2024-01-05 00:00:00
2024-01-06 00:00:00
2024-01-07 00:00:00
2024-01-08 00:00:00
2024-01-15 00:00:00
2024-01-22 00:00:00
2024-01-29 00:00:00
2024-02-01 00:00:00
2024-02-02 00:00:00
2024-02-03 00:00:00

This means your reference site " elmah.io " is interpreting this pattern incorrectly. In addition to that, I do not think this library has any way to match the first weekday of the month, so you'll either have to make this a feature request or look for a library that supports the 'nth weekday' specifier. In your case, using a library that supports this feature, you could use a pattern such as '0 0 MON#1' to achieve 00:00 at the first Monday of every month."