cronlaterjs

laterjs custom time period


I am using laterjs to define a custom time period to run during forex trading hours. However, my custom period seems to schedule to run even outside the defined period. I tried searching online for examples but there doesn't seem to be many relating to this library. I've looked at nodecron as well but cron syntax didn't seem to support my requirement, which was to run a task every hour, from X AM on Monday to Y PM on Friday. Here's my scheduler code:

later.forexWeek = {
  name: 'forex trading hours',
  range: later.h.range * 119,
  val: function(d) {
    return 0;
  },
  isValid: function(d, val) {
    return later.forexWeek.val(d) === val;
  },
  extent: function(d) { return [0, 1]; },
  start: function(d) {
    return later.date.next(
      later.Y.val(d), later.M.val(d), later.dw.val(1), 21
    );
  },
  end: function(d) {
    return later.date.prev(
      later.Y.val(d), later.M.val(d), later.dw.val(6), 20
    );
  },
  next: function(d, val) {
    return later.date.next(
      later.Y.val(d), later.M.val(d), later.D.val(d), later.H.val(d)
    );
  },
  prev: function(d, val) {
    return later.date.prev(
      later.Y.val(d), later.M.val(d), later.D.val(d), later.H.val(d)
    );
  }
};

var forexWeek = later.parse.recur().every().hour().on(0).customPeriod('forexWeek');
later.setInterval(function() {
  console.log(moment().format());
}, forexWeek);

Any help would be much appreciated!


Solution

  • You don't really need to write a custom time period for this type of schedule, Laterjs supports it directly. For example, if you want to run something every hour from 8AM on Monday until 5PM on Friday you would go through the following process to develop the schedule.

    Since there are different constraints on different days, we'll need to create a composite schedule. A composite schedule is basically a composition of different constraint sets which makes a particular occurrence valid if any of the constraint sets are valid. In this case, we'll have three different sets of constraints:

     1. Once every hour on the hour on Mondays after 8 AM
     2. Once every hour on the hour on Tuesdays, Wednesdays, Thursdays
     3. Once every hour on the hour on Fridays before and including 5PM
    

    So now we can create the appropriate schedule for each. Since Laterjs schedules are just JSON objects, I'll just manually create the schedule using the constraints defined at http://bunkat.github.io/later/time-periods.html#overview. The same schedule could be produced using the Recur parser as well.

    Translating the schedules that we defined previously:

     1. {dw: [2], h_a:[8], m:[0], s:[0]}
     2. {dw: [3,4,5], m:[0], s:[0]}
     3. {dw: [6], h_b:[18], m:[0], s:[0]}
    

    If we take the first one and break it down, it specifically says that a time should be considered valid when the day of the week (dw) value is 2 (Monday), when the hour value is greater than or equal to (h_a) 8, when the minute value (m) is equal to 0, and when the second value (s) is equal to 0. Any time that meets all these constraints would be returned by this schedule. It might be more clear if we look at a couple of examples.

    Mon Aug 11 2014 18:00:00 GMT-0700 (Pacific Daylight Time)
    
     - Day of week is 2
     - Hour is 18
     - Minute is 0
     - Second is 0
    
    This is a valid time and would be returned.
    
    Mon Aug 11 2014 7:00:00 GMT-0700 (Pacific Daylight Time)
    
     - Day of week is 2
     - Hour is 7
    
     Hour is not valid, this time would not be returned.
    

    The other two can be reasoned about in the same way. Now all we need to do is put them into a composite schedule which will basically OR them together so that a time that meets any of the schedules will be considered valid.

    var s = {schedules: [
        {dw: [2], h_a:[8], m:[0], s:[0]},
        {dw: [3,4,5], m:[0], s:[0]},
        {dw: [6], h_b:[18], m:[0], s:[0]}
    ]};
    

    Now you can find future (or past occurrences):

    later.schedule(s).next(100)