Git Product home page Git Product logo

cron-parser's Introduction

cron-parser

Build Status NPM version

Node.js library for parsing and manipulating crontab instructions. It includes support for timezones and DST transitions.

Compatibility
Node >= 12.0.0 TypeScript >= 4.2

Setup

npm install cron-parser

Supported format

*    *    *    *    *    *
┬    ┬    ┬    ┬    ┬    ┬
│    │    │    │    │    |
│    │    │    │    │    └ day of week (0 - 7, 1L - 7L) (0 or 7 is Sun)
│    │    │    │    └───── month (1 - 12)
│    │    │    └────────── day of month (1 - 31, L)
│    │    └─────────────── hour (0 - 23)
│    └──────────────────── minute (0 - 59)
└───────────────────────── second (0 - 59, optional)

Supports mixed use of ranges and range increments (W character not supported currently). See tests for examples.

Usage

Simple expression.

var parser = require('cron-parser');

try {
  var interval = parser.parseExpression('*/2 * * * *');

  console.log('Date: ', interval.next().toString()); // Sat Dec 29 2012 00:42:00 GMT+0200 (EET)
  console.log('Date: ', interval.next().toString()); // Sat Dec 29 2012 00:44:00 GMT+0200 (EET)

  console.log('Date: ', interval.prev().toString()); // Sat Dec 29 2012 00:42:00 GMT+0200 (EET)
  console.log('Date: ', interval.prev().toString()); // Sat Dec 29 2012 00:40:00 GMT+0200 (EET)
} catch (err) {
  console.log('Error: ' + err.message);
}

Iteration with limited timespan. Also returns ES6 compatible iterator (when iterator flag is set to true).

var parser = require('cron-parser');

var options = {
  currentDate: new Date('Wed, 26 Dec 2012 12:38:53 UTC'),
  endDate: new Date('Wed, 26 Dec 2012 14:40:00 UTC'),
  iterator: true
};

try {
  var interval = parser.parseExpression('*/22 * * * *', options);

  while (true) {
    try {
      var obj = interval.next();
      console.log('value:', obj.value.toString(), 'done:', obj.done);
    } catch (e) {
      break;
    }
  }

  // value: Wed Dec 26 2012 14:44:00 GMT+0200 (EET) done: false
  // value: Wed Dec 26 2012 15:00:00 GMT+0200 (EET) done: false
  // value: Wed Dec 26 2012 15:22:00 GMT+0200 (EET) done: false
  // value: Wed Dec 26 2012 15:44:00 GMT+0200 (EET) done: false
  // value: Wed Dec 26 2012 16:00:00 GMT+0200 (EET) done: false
  // value: Wed Dec 26 2012 16:22:00 GMT+0200 (EET) done: true
} catch (err) {
  console.log('Error: ' + err.message);
}

Timezone support

var parser = require('cron-parser');

var options = {
  currentDate: '2016-03-27 00:00:01',
  tz: 'Europe/Athens'
};

try {
  var interval = parser.parseExpression('0 * * * *', options);

  console.log('Date: ', interval.next().toString()); // Date:  Sun Mar 27 2016 01:00:00 GMT+0200
  console.log('Date: ', interval.next().toString()); // Date:  Sun Mar 27 2016 02:00:00 GMT+0200
  console.log('Date: ', interval.next().toString()); // Date:  Sun Mar 27 2016 04:00:00 GMT+0300 (Notice DST transition)
} catch (err) {
  console.log('Error: ' + err.message);
}

Manipulation

var parser = require('cron-parser');

var interval = parser.parseExpression('0 7 * * 0-4');
var fields = JSON.parse(JSON.stringify(interval.fields)); // Fields is immutable
fields.hour = [8];
fields.minute = [29];
fields.dayOfWeek = [1,3,4,5,6,7];
var modifiedInterval = parser.fieldsToExpression(fields);
var cronString = modifiedInterval.stringify();
console.log(cronString); // "29 8 * * 1,3-7"

Options

  • currentDate - Start date of the iteration
  • endDate - End date of the iteration

currentDate and endDate accept string, integer and Date as input.

In case of using string as input, not every string format accepted by the Date constructor will work correctly. The supported formats are:

The reason being that those are the formats accepted by the luxon library which is being used to handle dates.

Using Date as an input can be problematic specially when using the tz option. The issue being that, when creating a new Date object without any timezone information, it will be created in the timezone of the system that is running the code. This (most of times) won't be what the user will be expecting. Using one of the supported string formats will solve the issue(see timezone example).

  • iterator - Return ES6 compatible iterator object
  • utc - Enable UTC
  • tz - Timezone string. It won't be used in case utc is enabled

Last weekday of the month

This library supports parsing the range 0L - 7L in the weekday position of the cron expression, where the L means "last occurrence of this weekday for the month in progress".

For example, the following expression will run on the last monday of the month at midnight:

0 0 0 * * 1L

The library also supports combining L expressions with other weekday expressions. For example, the following cron will run every Monday as well as the last Wednesday of the month:

0 0 0 * * 1,3L

cron-parser's People

Contributors

albertorestifo avatar amiram avatar andytson avatar avindra avatar backsapce avatar bjonica avatar bvaughn avatar cesarandreu avatar diskimage avatar donbrinn avatar dprentis avatar faazshift avatar fishcharlie avatar harrisiirak avatar heitara avatar iamjochem avatar jonhester avatar kusold avatar lfreneda avatar martin-helmich avatar meaglin avatar mrose17 avatar nickclaw avatar rankida avatar regevbr avatar richorama avatar santigimeno avatar skyksandr avatar tenbits avatar vanodevium avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cron-parser's Issues

Does not support 'L'?

Again thanks for building this. This would make it better :)

Error: Invalid characters, got value: L
at Function._parseField (/usr/local/src/nodejs/voodoo/services/core/node_modules/cron-parser/lib/expression.js:129:11)
at parse (/usr/local/src/nodejs/voodoo/services/core/node_modules/cron-parser/lib/expression.js:566:36)
at Function.parse (/usr/local/src/nodejs/voodoo/services/core/node_modules/cron-parser/lib/expression.js:586:12)
at Function.parseExpression (/usr/local/src/nodejs/voodoo/services/core/node_modules/cron-parser/lib/parser.js:39:25)

timezone woes

hi. i am in us/pacific, and you can probably see where this is going (-;

console.log(new Date());
CronExpression.parse('00 45 08 * * 1', function(err, interval) {
for (var i = 0; i < 5; i++) console.log(interval.next());
});

yields:

Wed May 15 2013 15:34:28 GMT-0700 (PDT)

Mon May 20 2013 00:45:00 GMT-0700 (PDT)
Mon May 27 2013 00:45:00 GMT-0700 (PDT)
Mon Jul 01 2013 00:45:00 GMT-0700 (PDT)
Mon Jul 08 2013 00:45:00 GMT-0700 (PDT)
Mon Jul 15 2013 00:45:00 GMT-0700 (PDT)

in which the first line (the current date/time is right, but the next() intervals generated by cron-parser are off by the GMT distance.

pilot error on my part? or a bug?

thanks,

/mtr

Whitespace ... leniency

hi there,

crontab definitions are lenient with regard to the white space seperating the components of a schedule definition so that the following two lines are equivalent:

* 0    7,15       *    1-6
* 0 7,15 * 1-6

It is quite common for tabs to be used crontab files, unfortunately you module only accepts a single space as a delimiter between the components (mutiple spaces and/or tabs lead to parsing errors)

It would be nice if the parser could automatically normalize the input so that whitespace in a "schedule string" is treated the same way as is done by the various well-known cron applications found on posix systems. the normalization would need to be/do something like the following:

function normalize(input) 
{
   return (input + '').replace(/\s+/g, ' ').trim();
}

var testval = '0    7,15       *    1-6'
console.log(testval, normalize(testval));

Or maybe this is something you are opposed to?

To modify cron expression from one timezone to UTC

I need something like this:

newCronExpression = convert (oneCronExpression, fromTimezone, "UTC")

Let me give you one example:

My local timezone is IST i.e. GMT+5.30.

Current local time is: 11:20 AM.

I want a job to run in 45 min of every hour.

So, my cron expression: 45 * * * *

Hence I am expecting my job to run after 25 min ( as starting time is 11:45 AM)

but my job is running as per UTC.

Current time in UTC : 05:50 AM

As per cron expression 45 * * * , the starting time will be 06:45 AM at GMT.

So, the job will be actually started after 55 min.

Expected : After 25 min

Actual : After 55 min

So,

if I am converting my local cron expression 45 * * * to 15 * * * * at GMT, then actual waiting period will be same as expected.

The question is how will I convert my local cron expression to GMT for all usecase

Is this possible by using your library.

freeze, if value is out of range

For example, if you try to parse cron expression like '0 0 4 30 2 *', you got freeze. I know, this is incorrect expression, because february have < 30 days, but i guess, there should be exception, or error, but not freezing.

'endDate' option not working

Hello,

I'm testing the example code with 'currentDate' and 'endDate' option, but, the endDate option is not respected.

Here's the code:

var parser = require('cron-parser');

var start = new Date();
var end = new Date('Tue, 31 Mar 2015 12:00:00 BRT');

var options = {
   currentDate: start,
   endDate: end,
   iterator: true
 };

 try{
   var interval = parser.parseExpression('*/2 * * * *', options);

   while(true){
     try{
       console.log(interval.next());
       /*
        Output:

{ value: Tue Mar 31 2015 11:34:00 GMT-0300 (BRT), done: false } // The start date is OK...
{ value: Tue Mar 31 2015 11:36:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 11:38:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 11:40:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 11:42:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 11:44:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 11:46:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 11:48:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 11:50:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 11:52:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 11:54:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 11:56:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 11:58:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:00:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:02:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:04:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:06:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:08:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:10:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:12:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:14:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:16:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:18:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:20:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:22:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:24:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:26:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:28:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:30:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:32:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:34:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:36:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:38:00 GMT-0300 (BRT), done: false }
{ value: Tue Mar 31 2015 12:40:00 GMT-0300 (BRT), done: false } // ... But the end is not.
        */
     } catch(e){
       break;
     }
   }

 }catch(err){
   console.log(err.message);
 }

Am I doing something wrong?

Thanks!

Infinite loop for timezones that changes to Summer Time in hour 00:00h

I got an infinite loop in the code above:

 var parser = require('cron-parser');
 var interval = parser.parseExpression('0 0 0 10 * *');
 console.log(interval.next());

The cause of it is the code:

/**
 * Increment day
 */
Date.prototype.addDay = function addDay () {
  this.setDate(this.getDate() + 1);
  this.setHours(0);
  this.setMinutes(0);
  this.setSeconds(0);
};

See: https://github.com/harrisiirak/cron-parser/blob/master/lib/date.js#L30

This bug only happens if in your timezone the DST starts at 00:00h. For example, in the timezone BRT that starts the DST in 19/10/2014 00:00h, the function addDayfor the date 18/10/2014 00:00:00 results in the date 18/10/2014 23:00:00.

I write the test above to simulate the bug. If you change timezone of your machine to BRT you will get a timeout in this test:

test('Summertime bug test', function(t) {
  var month = new Date().getMonth() + 1;
  CronExpression.parse('0 0 0 1 '+month+' *', function(err, interval) {
    t.ifError(err, 'Interval parse error');
    t.ok(interval, 'Interval parsed');

    var next = interval.next();

    // Before fix the bug it was getting a timeout error if you are
    // in a timezone that changes the DST to ST in the hour 00:00h.
    t.ok(next, 'Found next scheduled interval');

    t.end();
  });
});

You can found more timezones like BRT in http://www.worldtimezone.com/daylight.html.

Not incrementing interval

I saw this should have been fixed in version 1.1.1, so I upgraded till latest version (2.3.1).

But still failing (and not in the second iteration, but in the first)

This is the source code:

var next; 

        try {
            next = cronParser.parseExpression(task.repeat)
                .next().toString();
            if(task.name == 'bidQueue'){
            	console.log("Repeat: " + task.repeat);
            	console.log("Now: " + new Date());
            	console.log("Next1: " + next);
            }
            next = new Date(next);
            if(task.name == 'bidQueue')
            	console.log("Next2: " + next);
        } catch (e) {
            console.error('Error setting up cron job (' + task.name +
                ').', e.message || e);
            return alias;
        }

And this is the output:

Repeat: * * * * *
Now: Tue Feb 21 2017 16:45:00 GMT+0100 (CET)
Next1: Tue Feb 21 2017 16:45:00 GMT+0100
Next2: Tue Feb 21 2017 16:45:00 GMT+0100 (CET)

As you see, Next1 and Next2 should have been incremented in 1 minute, but the time is the same as Now

Invalid explicit day of month definition

0 47 22 * * 3

[ERROR] error - Caught exception: Error: Invalid explicit day of month definition
at CronExpression.findSchedule (/Users/**/dev/analy-engine/node_modules/cron-parser/lib/expression.js:388:15)
at CronExpression.next (/Users/_/dev/analy-engine/node_modules/cron-parser/lib/expression.js:455:23)
at scheduleNextRecurrence (/Users/
_/dev/analy-engine/node_modules/node-schedule/lib/schedule.js:449:90)
at null.onTimeout (/Users/**/dev/analy-engine/node_modules/node-schedule/lib/schedule.js:408:19)
at Timer.listOnTimeout (timers.js:92:15)

3q~

Seconds are not part of the usual cron spec!

using them without explicit warning about that is quite broken.

I think that seconds should be allowed only with a specific flag/boolean, and not in causal parsing. just caused me an evil an unexpected bug

.validate() method

Does this library has a .validate() method (to validate passed string, as eligible CRON instruction)?

Previous match

I want to use this to run a SQL query periodically, filtered between the last two match times.

So it looks like I need to be able to iterate backwards in time.

Is that possible using this tool?

Bug with monthly parsing

test code

var parser = require('cron-parser');

var interval = parser.parseExpressionSync('40 0 1 * *');
console.log('Date: ', interval.next());
console.log('Date: ', interval.next());
console.log('Date: ', interval.next());
console.log('Date: ', interval.next());

output actual:

Date:  Thu May 01 2014 00:40:00 GMT-0600 (MDT)
Date:  Tue Jul 01 2014 00:40:00 GMT-0600 (MDT)
Date:  Fri Aug 01 2014 00:40:00 GMT-0600 (MDT)
Date:  Wed Oct 01 2014 00:40:00 GMT-0600 (MDT)

output expected:

Date:  Thu May 01 2014 00:40:00 GMT-0600 (MDT)
Date:  Sun Jun 01 2014 00:40:00 GMT-0600 (MDT)
Date:  Tue Jul 01 2014 00:40:00 GMT-0600 (MDT)
Date:  Fri Aug 01 2014 00:40:00 GMT-0600 (MDT)

system:

$ npm -v
1.3.17
$ node -v
v0.10.23
$ npm list
/tmp
└── [email protected]

remove parseExpressionSync??

Reading then code it's not entirely clear if the sync version of parsing is the one to use or if the async is the one to use.

Can you give a head's up on this. Maybe via the readme

next() on newly parsed expression returning past value

We have a job that runs every minute, and it causes an issue where parseExpression() will return a job whose first run time is actually in the past. Here's a simply reproduction:

var cron_parser = require("cron-parser");
var minuteStart = new Date(cron_parser.parseExpression("* * * * *").next().toString());

setTimeout(function() {
    console.log(Date.now());

    console.log(new Date(cron_parser.parseExpression("* * * * *").next().toString()).getTime());
}, minuteStart - new Date());

// result
1459566240061 - now
1459566240000 - next run time, in the past???

From the output you can see that the first console.log of what time it is now and the parseExpression that occurs after it yet has a date stamp preceding what time it actually is. The only way i'm able to consistently get this to happen is in conjunction with a setTimeout that puts my node instance right around the minute point. At first I thought possible Node was firing the setTimeout prior to the timeout value, but from my tests this is not the case. This is occurring on Node 5.9.0.

toUTC() nonexistent

In the README, there's this example:

  console.log('Date: ', interval.next().toUTC().toString());

But when I try it, I get an error:

const parser = require('cron-parser');

const interval = parser.parseExpression('*/20 * * * *');
console.log(interval.next().toUTC());
console.log(interval.next().toUTC());
                            ^

TypeError: interval.next(...).toUTC is not a function

Invalid day of month with December

Hy
Maybe it's juste me, but when I try to get the next execution date with this cron line: '9 22 December 12 4', everything is correct, but the day of the month is invalid ..

Have anyone seen this problem before?

It might be an issue

I'm afraid of making a mistake but I have to ask you guys.

Having the code below:

var config = "03 17,18 * * *"
// it prompts program to run forever
setInterval(function() {
    log("silly", "Time debugging:" + Date());
}, 5000);

log("silly", "Cron configuration: " + config);
cron.scheduleJob(config, function() {
    log("silly", "Cron event time triggered at " + Date());
});

I got the out listed below:

silly: Cron configuration: 03 17,18 * * * (index.js)
silly: Time debugging:Thu Feb 18 2016 17:02:55 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:00 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:05 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:10 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:15 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:20 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:25 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:30 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:35 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:40 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:45 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:50 GMT+0000 (UTC) (index.js)
silly: Time debugging:Thu Feb 18 2016 17:03:55 GMT+0000 (UTC) (index.js)

I expect that at least one event is triggered at 17:03, but it doesn't happen.

I have parse the expression (03 17,18 * * *) manually and it's right.

What I'm doing wrong?

next() no longer returns a Date

In previous versions next() used to return a Date, now it returns a CronDate. I was wondering if that change was done with intent or was accidental.

If it was intentional then I have a couple possible ideas:

  1. From looking at the code it appears that date.js is basically just a proxy to moment(), my question is why not just cut out the middle-man, eliminate date.js and have next() actually return the moment? Moment is a fairly well documented library and most devs know how to interact with it. If next() returned a moment() it would be simple to get to the raw date value by just doing moment's toDate() and since it's a moment obj I have access to all of the various methods and features that moment has.
  2. If you don't want to expose the moment dependency, then I would propose adding a toDate() to CronDate that proxies to moments() toDate() so that we can get access to the Date obj. In the old version when it returned date objects this wasn't necessary, but now that it does I end up needing to do awkward things like new Date(interval.next().toString() in order to get the date obj.

Every second behavior

var now = new Date(); 
var cron = require('cron-parser'); 
var s = cron.parseExpression('* * * * * *', {currentDate: now, iterator: true}); 
console.log(`now: ${now.toString()}, next: ${s.next().value}`);
// -> now: Tue Dec 15 2015 10:11:52 GMT+0100 (CET), next: Tue Dec 15 2015 10:11:52 GMT+0100 (CET)

Is this expected result (the two dates are the same)? I would expect the next to be 1sec in the future.

iterator mode is very slow

var parser = require('cron-parser');

var interval = parser.parseExpression('0 * * * *', {
    iterator: true,
    currentDate: new Date().toISOString(),
});

var now = Date.now();
interval.next().value;
console.log('Operation took: ' + (Date.now() - now) + 'ms');
// Operation took: 3924ms
var parser = require('cron-parser');

var interval = parser.parseExpression('0 * * * *', {
    // iterator: true,
    currentDate: new Date().toISOString(),
});

var now = Date.now();
interval.next(); // no .value
console.log('Operation took: ' + (Date.now() - now) + 'ms');
// Operation took: 21ms

I did a little debugging and it looks like you recursively call next a lot to get the value of done.

DST shift handled incorrectly sometimes

Please let me know if I'm understanding something incorrectly

The following javascript

const cronParser = require("cron-parser");
const moment = require("moment");

const scheduleForDay = (event, date) => {
  let earlier = moment(date).subtract(2, "hours");
  let later   = moment(date).add(24, "hours");

  console.log(`\nChecking dates between ${earlier.toString()} and ${later.toString()} for ${event.timezone} with frequency "${event.frequency}"`);

  let interval = cronParser.parseExpression(event.frequency, {
    currentDate : earlier,
    endDate     : later,
    tz          : event.timezone,
    iterator    : true
  });

  while (true) {
    try {
      let datetime = interval.next().value.toDate();
      let localTime = moment(datetime).tz(event.timezone).toString();
      console.log(`Scheduled event for ${moment(datetime).utc().toString()} (${localTime} in local time)`);
    } catch (e) {
      break;
    }
  }
}

scheduleForDay({ timezone: "Europe/Berlin",    frequency: "30 2 * * *" }, moment("2016-03-27").tz("Europe/Berlin"));
scheduleForDay({ timezone: "Europe/Berlin",    frequency: "30 2 * * *" }, moment("2016-10-30").tz("Europe/Berlin"));
scheduleForDay({ timezone: "America/New_York", frequency: "30 1 * * *" }, moment("2016-03-13").tz("America/New_York"));
scheduleForDay({ timezone: "America/New_York", frequency: "30 1 * * *" }, moment("2016-11-06").tz("America/New_York"));

Produces this output

Checking dates between Sat Mar 26 2016 22:00:00 GMT+0100 and Mon Mar 28 2016 01:00:00 GMT+0200 for Europe/Berlin with frequency "30 2 * * *"
Scheduled event for Sun Mar 27 2016 01:30:00 GMT+0000 (Sun Mar 27 2016 03:30:00 GMT+0200 in local time)

Checking dates between Sat Oct 29 2016 22:00:00 GMT+0200 and Sun Oct 30 2016 23:00:00 GMT+0100 for Europe/Berlin with frequency "30 2 * * *"
Scheduled event for Sun Oct 30 2016 00:30:00 GMT+0000 (Sun Oct 30 2016 02:30:00 GMT+0200 in local time)

Checking dates between Sat Mar 12 2016 16:00:00 GMT-0500 and Sun Mar 13 2016 19:00:00 GMT-0400 for America/New_York with frequency "30 1 * * *"
Scheduled event for Sun Mar 13 2016 06:30:00 GMT+0000 (Sun Mar 13 2016 01:30:00 GMT-0500 in local time)
Scheduled event for Sun Mar 13 2016 07:30:00 GMT+0000 (Sun Mar 13 2016 03:30:00 GMT-0400 in local time)

Checking dates between Sat Nov 05 2016 17:00:00 GMT-0400 and Sun Nov 06 2016 18:00:00 GMT-0500 for America/New_York with frequency "30 1 * * *"
Scheduled event for Sun Nov 06 2016 05:30:00 GMT+0000 (Sun Nov 06 2016 01:30:00 GMT-0400 in local time)

I would expect that if you want something to happen once a day, it should happen once and only once.

It seems to handle both timeshifts in Berlin properly. However, New York is a little weird.

When NY goes backward from 2 and ends up having two 1:30s, it handles it properly, only having a single event.

When NY goes forward from 2 to 3, it ends up triggering the 1:30 event twice, even though I would expect 2:30 to be a more problematic time.

iterator.next() is extremely slow

I modified the example code to remove the current and end dates, as I want to have an iterator that will work indefinitely (see below).

var options = {
  iterator: true
};

For some reason, when used this way, .next() is extremely slow. I added back in currentDate and endDate, and I noticed that the larger the gap between those two, the slower .next() was.

Add browser support

The parseExpression function could be useful for browser-based users. Unfortunately, importing the library via webpack causes an error:

ERROR in ./~/cron-parser/lib/parser.js
Module not found: Error: Cannot resolve module 'fs' in /path/to/project/node_modules/cron-parser/lib
 @ ./~/cron-parser/lib/parser.js 93:2-15

Would you be willing to package this in such a way as to either expose CronExpression.parse or allow the parseExpression to be used without triggering the import?

Feature Request: Previous interval

I'm using cron-parser to write an archiving tool. A given cron expression determines in what intervals files get archived. Right now I'm saving the archive file using the archive-creation date, but it would be really nice if there were a way to get the previous interval.

For example, if I created files yesterday (Nov 4th), and I archived them daily 0 0 * * * then my resulting archive would be named archive_2015-11-5.tar.bz2. While Nov. 5th describes the date the archive was created, it doesn't describe the contents of the archive. If there were a way to get the previous interval, I could create archives named archive_2015-11-4_to_2015-11-5.tar.bz2.

Is getting the previous interval a feature that fits cron-parser?

Issue on interval.getNext()

var interval = CronParser.parseExpression('* 2 * * *', {currentDate: new Date('2016-02-08T21:49:22.527Z')});
console.log(interval.next());

I get the error "Invalid explicit day of month definition"

Does not support '?'

Do you think it would be possible to add support for '?'. This lib has saved me heaps of time thanks for building it :)

Error: Invalid characters, got value: ?
at Function._parseField (/usr/local/src/nodejs/voodoo/services/core/node_modules/cron-parser/lib/expression.js:129:11)
at parse (/usr/local/src/nodejs/voodoo/services/core/node_modules/cron-parser/lib/expression.js:566:36)
at Function.parse (/usr/local/src/nodejs/voodoo/services/core/node_modules/cron-parser/lib/expression.js:586:12)
at Function.parseExpression (/usr/local/src/nodejs/voodoo/services/core/node_modules/cron-parser/lib/parser.js:39:25)

Problem when define unordered hours list

I have a cron definition to run at minute 0 past hour 1, 9, and 11:

  • When I defined in this way: 0 9,11,1 * * * (the job is not running at 1)
  • When I defined in this way: 0 1,9,11 * * * (it's running correctly)

I am using node-schedule and I have reported the issue to them, too.

Thanks!

Stuck in while loop indefinitely

I found a minimal repro case, it always gets stuck in the 27th cycle (script never ends)

var expression = "0 12 * * *"
var cron = require("cron-parser")
var currentDate = new Date().toISOString()

var iterator = cron.parseExpression(expression, {currentDate:currentDate})

for (var i=0; i<40;i++) {
  console.log(iterator.next().getTime())
}

I have also tried to recreate the parser on every iteration of the loop, but the results were the same.
Any idea what it might be?
Thanks

iterate with for...of

It seems you didn't implement Symbol.iterator thus can't iterate via for...of:

const interval = CronExpression.parse('0 * * * *', options)
for (let i of interval) {
    console.log(i.value.toString())
}

Seconds unsupported?

Hello, thanks for this library, very useful.

The documentation mentions that seconds are optional, but when I specify them, it appears to have no effect. For example:

parser = require('cron-parser');
interval = parser.parseExpression('* * * * * *');
interval.next(); // => Wed Feb 04 2015 16:06:00 GMT-0500 (EST)
interval.next(); // => Wed Feb 04 2015 16:07:00 GMT-0500 (EST)
interval.next(); // => Wed Feb 04 2015 16:08:00 GMT-0500 (EST)

Similarly with an every-n-seconds expression:

interval = parser.parseExpression('*/30 * * * * *');
interval.next(); // => Wed Feb 04 2015 16:08:00 GMT-0500 (EST)
interval.next(); // => Wed Feb 04 2015 16:09:00 GMT-0500 (EST)

My use case for this is a bot that reports statistics on the hour by default, but which I can run locally with a ten-second reporting interval so I don’t have to wait for results. I was using an interval in milliseconds before, but it’s desirable to be able to report the statistics on the exact hour mark instead of just once an hour.

Am I doing something incorrectly? I did fork the repository and have a look at fixing it myself but it seemed pretty complicated in there. Maybe it would be simpler for you to reach in directly for the fix, but if not, I could give it another try.

defined both day and weekday..

if defined both day and weekday, the parser should check day OR weekday. This is the same issue as here bunkat/later#11

man 5 crontab:
Note: The day of a command's execution can be specified by two fields — day of month, and day of week. If both fields are restricted (i.e., aren't *), the command will be run when either field matches the current time.

Issue when the next date is in the next month

Hi and thanks a lot for your great module !

There is a bug with this cron expression :

var options = { 
  currentDate: new Date('2013-10-31 17:00:00') 
}; 

parser.parseExpression('0 16 * * 4', options, function(err, interval) { 
  while (true) { 
    try { 
        console.log(interval.next()); 
    } catch (e) { 
        break; 
    } 
  } 

The next date here will be 2013-12-05 instead of 2013-11-07 !

Thanks

setters on CronExpression

Do you think this might something you'd consider? At the moment I have to manage the cron string (which is fine) but it seems like it would be more elegant if this library allowed you to set the hour or day and get back the toString() version of the CronExpression.

The parseSync naming is misleading

As far as I can see all of these methods apart from the CronParser.parseFile() are synchronous in that they call the passed callback before the called method returns.

It would be nice to make this clear in the README and to remove incorrect documentation such as: https://github.com/harrisiirak/cron-parser/blob/master/lib/expression.js#L490

I'm not sure if you can change the api now, but one alternative would be to use the callback if provided otherwise just return the parsed expression.

wrong get next time

var nextTime = parser.parseExpressionSync("0 23 * * 5",{"currentDate": new Date(Date.parse('2014-10-23'))}).next();
console.log(nextTime)
var nextTime = parser.parseExpressionSync("0 23 * * 5",{"currentDate": new Date(Date.parse('2014-10-25'))}).next();
console.log(nextTime)

gives:

Fri Oct 24 2014 23:00:00 GMT+0200 (CEST)
Fri Oct 31 2014 23:00:00 GMT+0100 (CET)

I think it should be one trigger on friday the 31th aswell?

Hangs finding invalid values

I'm considering using this module to replace the CronTime code in the cron project. However, one of my tests is failing to do anything because this module runs into the same issue that my CronTime code used to. I'm sharing the issue here so that you can take a look at what I did and see if it works for you or in case you have a better alternative.

https://github.com/ncb000gt/node-cron/issues/79

I wont be able to use this module until this is fixed as I don't want to expose any regressions my module. :) Thanks for taking a look.

Monthly and yearly cron errors

I found this issue in the released version 0.4.4.

For the code:

parser.parseExpression('0 0 0 1 1 *', function(err, interval) {
  var count = 5;
  while (count) {
    try {
        console.log(interval.next());
        count--;
    } catch (e) {
        break;
    }
  }
});

I got the output:

Wed Oct 22 2014 00:00:00 GMT+0300 (EEST)
Thu Oct 23 2014 00:00:00 GMT+0300 (EEST)
Fri Oct 24 2014 00:00:00 GMT+0300 (EEST)
Sat Oct 25 2014 00:00:00 GMT+0300 (EEST)
Sun Oct 26 2014 00:00:00 GMT+0300 (EEST)

If i run the same code in the version 0.4.3 it works fine:

Thu Oct 01 2015 00:00:00 GMT+0300 (EEST)
Sat Oct 01 2016 00:00:00 GMT+0300 (EEST)
Sun Oct 01 2017 00:00:00 GMT+0300 (EEST)
Mon Oct 01 2018 00:00:00 GMT+0300 (EEST)
Tue Oct 01 2019 00:00:00 GMT+0300 (EEST)

The same problem seems to happen with the expression '0 0 0 1 * *'.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.