diff --git a/src/farm_designer/farm_events/calendar/__tests__/scheduler_test.ts b/src/farm_designer/farm_events/calendar/__tests__/scheduler_test.ts new file mode 100644 index 000000000..06f5ef8d4 --- /dev/null +++ b/src/farm_designer/farm_events/calendar/__tests__/scheduler_test.ts @@ -0,0 +1,47 @@ +import { scheduler } from "../scheduler"; +import * as moment from "moment"; + +describe("scheduler", () => { + it("runs a schedule", () => { + // 8am Monday + let monday = moment() + .add(14, "days") + .startOf("isoWeek") + .startOf("day") + .add(8, "hours"); + // 3am Tuesday + let tuesday = monday.clone().add(19, "hours"); + // 18pm Thursday + let thursday = monday.clone().add(3, "days").add(10, "hours"); + let interval = moment.duration(4, "hours").asSeconds(); + let result1 = scheduler({ + originTime: monday, + intervalSeconds: interval, + lowerBound: tuesday, + upperBound: thursday + }); + expect(result1[0].format("dd")).toEqual("Tu"); + expect(result1[0].hour()).toEqual(4); + expect(result1.length).toEqual(16); + const EXPECTED = [ + "04:00am Tu", + "08:00am Tu", + "12:00pm Tu", + "04:00pm Tu", + "08:00pm Tu", + "12:00am We", + "04:00am We", + "08:00am We", + "12:00pm We", + "04:00pm We", + "08:00pm We", + "12:00am Th", + "04:00am Th", + "08:00am Th", + "12:00pm Th", + "04:00pm Th" + ]; + const REALITY = result1.map(x => x.format("hh:mma dd")); + EXPECTED.map(x => expect(REALITY).toContain(x)); + }); +}); diff --git a/src/farm_designer/farm_events/calendar/scheduler.ts b/src/farm_designer/farm_events/calendar/scheduler.ts new file mode 100644 index 000000000..b5fbf634d --- /dev/null +++ b/src/farm_designer/farm_events/calendar/scheduler.ts @@ -0,0 +1,36 @@ +import * as moment from "moment"; +import { Moment } from "moment"; +import { times, last } from "lodash"; + +interface SchedulerProps { + originTime: Moment; + intervalSeconds: number; + lowerBound: Moment; + upperBound?: Moment; +} + +export function scheduler({ originTime, + intervalSeconds, + lowerBound, + upperBound }: SchedulerProps): Moment[] { + + upperBound = upperBound || moment(moment().add(1, "year")); + // # How many items must we skip to get to the first occurence? + let skip_intervals = + Math.ceil((lowerBound.unix() - originTime.unix()) / intervalSeconds); + // # At what time does the first event occur? + let first_item = originTime + .clone() + .add((skip_intervals * intervalSeconds), "seconds"); + let list = [first_item]; + times(60, () => { + let x = last(list); + if (x) { + let item = x.clone().add(intervalSeconds, "seconds"); + if (item.isBefore(upperBound)) { + list.push(item); + } + } + }); + return list; +}