kelektiv / node-cron

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

Missing Cron Execution during DST change #881

Open ishan393 opened 2 months ago

ishan393 commented 2 months ago

Description

Hi, thanks to author and everyone contributing for making this amazing library possible.

Encountered an issue where the cron jobs aren't triggering during daylight saving change.

For example: TimeZone - Australia/Melbourne 7 Apr 2024 - Daylight savings time ended and clocks turned back 1 hour Time goes from 2:59 -> 2:00 (See example below)

Expected Behavior

The Cron job should trigger every half an hour (See example below)

Actual Behavior

The Cron job didn't trigger for one hour and missed two executions. Missing cron job executed log two times (See example below)

Steps to Reproduce

const { CronJob } = require("cron");
const fakeTImers = require("@sinonjs/fake-timers");

process.env.TZ = "Australia/Melbourne";

const main = () => {
  const clock = fakeTImers.install({
    now: new Date("2024-04-07T01:00:00.000"),
  });
  const job = new CronJob(
    "*/30 * * * *", // every 30 minutes
    function () {
      console.log(
        "Cron job executed. The current time is: ",
        new Date().toString()
      );
    },
    null,
    true,
    "Australia/Melbourne"
  );

  console.log("current time is: ", new Date().toString());
  console.log("Going to advance time by 30 minutes");
  clock.tick(1000 * 60 * 30);
  console.log("Time after advancing is ", new Date().toString());
  console.log("\n");

  console.log("current time is: ", new Date().toString());
  console.log("Going to advance time by 30 minutes");
  clock.tick(1000 * 60 * 30);
  console.log("Time after advancing is ", new Date().toString());
  console.log("\n");

  console.log("current time is: ", new Date().toString());
  console.log("Going to advance time by 30 minutes");
  clock.tick(1000 * 60 * 30);
  console.log("Time after advancing is ", new Date().toString());
  console.log("\n");

  console.log("current time is: ", new Date().toString());
  console.log("Going to advance time by 30 minutes");
  clock.tick(1000 * 60 * 30);
  console.log("Time after advancing is ", new Date().toString());
  console.log("\n");

  console.log("current time is: ", new Date().toString());
  console.log("Going to advance time by 30 minutes");
  clock.tick(1000 * 60 * 30);
  console.log("Time after advancing is ", new Date().toString());
  console.log("\n");

  console.log("current time is: ", new Date().toString());
  console.log("Going to advance time by 30 minutes");
  clock.tick(1000 * 60 * 30);
  console.log("Time after advancing is ", new Date().toString());
  console.log("\n");

  console.log("current time is: ", new Date().toString());
  console.log("Going to advance time by 30 minutes");
  clock.tick(1000 * 60 * 30);
  console.log("Time after advancing is ", new Date().toString());
  console.log("\n");
};

main();

Output:

current time is:  Sun Apr 07 2024 01:00:00 GMT+1100 (Australian Eastern Daylight Time)
Going to advance time by 30 minutes
Cron job executed. The current time is:  Sun Apr 07 2024 01:30:00 GMT+1100 (Australian Eastern Daylight Time)
Time after advancing is  Sun Apr 07 2024 01:30:00 GMT+1100 (Australian Eastern Daylight Time)

current time is:  Sun Apr 07 2024 01:30:00 GMT+1100 (Australian Eastern Daylight Time)
Going to advance time by 30 minutes
Cron job executed. The current time is:  Sun Apr 07 2024 02:00:00 GMT+1100 (Australian Eastern Daylight Time)
Time after advancing is  Sun Apr 07 2024 02:00:00 GMT+1100 (Australian Eastern Daylight Time)

current time is:  Sun Apr 07 2024 02:00:00 GMT+1100 (Australian Eastern Daylight Time)
Going to advance time by 30 minutes
Cron job executed. The current time is:  Sun Apr 07 2024 02:30:00 GMT+1100 (Australian Eastern Daylight Time)
Time after advancing is  Sun Apr 07 2024 02:30:00 GMT+1100 (Australian Eastern Daylight Time)

current time is:  Sun Apr 07 2024 02:30:00 GMT+1100 (Australian Eastern Daylight Time)
Going to advance time by 30 minutes
Time after advancing is  Sun Apr 07 2024 02:00:00 GMT+1000 (Australian Eastern Standard Time)

current time is:  Sun Apr 07 2024 02:00:00 GMT+1000 (Australian Eastern Standard Time)
Going to advance time by 30 minutes
Time after advancing is  Sun Apr 07 2024 02:30:00 GMT+1000 (Australian Eastern Standard Time)

current time is:  Sun Apr 07 2024 02:30:00 GMT+1000 (Australian Eastern Standard Time)
Going to advance time by 30 minutes
Cron job executed. The current time is:  Sun Apr 07 2024 03:00:00 GMT+1000 (Australian Eastern Standard Time)
Time after advancing is  Sun Apr 07 2024 03:00:00 GMT+1000 (Australian Eastern Standard Time)

current time is:  Sun Apr 07 2024 03:00:00 GMT+1000 (Australian Eastern Standard Time)
Going to advance time by 30 minutes
Cron job executed. The current time is:  Sun Apr 07 2024 03:30:00 GMT+1000 (Australian Eastern Standard Time)
Time after advancing is  Sun Apr 07 2024 03:30:00 GMT+1000 (Australian Eastern Standard Time)

Your Environment

Might be related to: #563 #638

sheerlox commented 1 month ago

Hi, thanks for reporting and providing a reproduction means.

I took note of the issue and will try to dedicate some time to it when possible.