From 58032738b9e260d625e5224c60fdd009f77d21fe Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Mon, 19 Feb 2018 17:04:04 +0100 Subject: [PATCH] chore(cron): replace luxon with moment-timezone (#2657) --- @xen-orchestra/cron/package.json | 2 +- @xen-orchestra/cron/src/index.js | 11 +++-- @xen-orchestra/cron/src/next.js | 59 +++++++++++++-------------- @xen-orchestra/cron/src/next.spec.js | 12 +++--- @xen-orchestra/cron/src/parse.js | 7 +--- @xen-orchestra/cron/src/parse.spec.js | 6 +-- yarn.lock | 10 ----- 7 files changed, 46 insertions(+), 61 deletions(-) diff --git a/@xen-orchestra/cron/package.json b/@xen-orchestra/cron/package.json index 2df725bfe..e085746d3 100644 --- a/@xen-orchestra/cron/package.json +++ b/@xen-orchestra/cron/package.json @@ -38,7 +38,7 @@ }, "dependencies": { "lodash": "^4.17.4", - "luxon": "^0.5.2" + "moment-timezone": "^0.5.14" }, "devDependencies": { "@babel/cli": "7.0.0-beta.40", diff --git a/@xen-orchestra/cron/src/index.js b/@xen-orchestra/cron/src/index.js index fd381c2dd..fffdb2021 100644 --- a/@xen-orchestra/cron/src/index.js +++ b/@xen-orchestra/cron/src/index.js @@ -1,4 +1,4 @@ -import { DateTime } from 'luxon' +import moment from 'moment-timezone' import next from './next' import parse from './parse' @@ -41,7 +41,10 @@ class Job { class Schedule { constructor (pattern, zone = 'utc') { this._schedule = parse(pattern) - this._dateTimeOpts = { zone } + this._createDate = + zone.toLowerCase() === 'utc' + ? moment.utc + : zone === 'local' ? moment : () => moment.tz(zone) } createJob (fn) { @@ -51,7 +54,7 @@ class Schedule { next (n) { const dates = new Array(n) const schedule = this._schedule - let date = DateTime.fromObject(this._dateTimeOpts) + let date = this._createDate() for (let i = 0; i < n; ++i) { dates[i] = (date = next(schedule, date)).toJSDate() } @@ -59,7 +62,7 @@ class Schedule { } _nextDelay () { - const now = DateTime.fromObject(this._dateTimeOpts) + const now = this._createDate() return next(this._schedule, now) - now } diff --git a/@xen-orchestra/cron/src/next.js b/@xen-orchestra/cron/src/next.js index 20448d5a2..cb7bbae3d 100644 --- a/@xen-orchestra/cron/src/next.js +++ b/@xen-orchestra/cron/src/next.js @@ -1,10 +1,10 @@ +import moment from 'moment-timezone' import sortedIndex from 'lodash/sortedIndex' -import { DateTime } from 'luxon' const NEXT_MAPPING = { month: { year: 1 }, - day: { month: 1 }, - weekday: { week: 1 }, + date: { month: 1 }, + day: { week: 1 }, hour: { day: 1 }, minute: { hour: 1 }, } @@ -13,38 +13,37 @@ const getFirst = values => (values !== undefined ? values[0] : 0) const setFirstAvailable = (date, unit, values) => { if (values === undefined) { - return date + return } const curr = date.get(unit) const next = values[sortedIndex(values, curr) % values.length] if (curr === next) { - return date + return } - const newDate = date.set({ [unit]: next }) - return newDate > date ? newDate : newDate.plus(NEXT_MAPPING[unit]) + const timestamp = +date + date.set(unit, next) + if (timestamp > +date) { + date.add(NEXT_MAPPING[unit]) + } + return true } // returns the next run, after the passed date export default (schedule, fromDate) => { - let date = fromDate + let date = moment(fromDate) .set({ second: 0, millisecond: 0, }) - .plus({ minute: 1 }) + .add({ minute: 1 }) const { minute, hour, dayOfMonth, month, dayOfWeek } = schedule - date = setFirstAvailable(date, 'minute', minute) + setFirstAvailable(date, 'minute', minute) - let tmp - - tmp = setFirstAvailable(date, 'hour', hour) - if (tmp !== date) { - date = tmp.set({ - minute: getFirst(minute), - }) + if (setFirstAvailable(date, 'hour', hour)) { + date.set('minute', getFirst(minute)) } let loop @@ -52,30 +51,30 @@ export default (schedule, fromDate) => { do { loop = false - tmp = setFirstAvailable(date, 'month', month) - if (tmp !== date) { - date = tmp.set({ - day: 1, + if (setFirstAvailable(date, 'month', month)) { + date.set({ + date: 1, hour: getFirst(hour), minute: getFirst(minute), }) } + let newDate = date.clone() if (dayOfMonth === undefined) { if (dayOfWeek !== undefined) { - tmp = setFirstAvailable(date, 'weekday', dayOfWeek) + setFirstAvailable(newDate, 'day', dayOfWeek) } } else if (dayOfWeek === undefined) { - tmp = setFirstAvailable(date, 'day', dayOfMonth) + setFirstAvailable(newDate, 'date', dayOfMonth) } else { - tmp = DateTime.min( - setFirstAvailable(date, 'day', dayOfMonth), - setFirstAvailable(date, 'weekday', dayOfWeek) - ) + const dateDay = newDate.clone() + setFirstAvailable(dateDay, 'date', dayOfMonth) + setFirstAvailable(newDate, 'day', dayOfWeek) + newDate = moment.min(dateDay, newDate) } - if (tmp !== date) { - loop = tmp.month !== date.month - date = tmp.set({ + if (+date !== +newDate) { + loop = date.month() !== newDate.month() + date = newDate.set({ hour: getFirst(hour), minute: getFirst(minute), }) diff --git a/@xen-orchestra/cron/src/next.spec.js b/@xen-orchestra/cron/src/next.spec.js index 842ce880e..471b397c4 100644 --- a/@xen-orchestra/cron/src/next.spec.js +++ b/@xen-orchestra/cron/src/next.spec.js @@ -1,17 +1,15 @@ /* eslint-env jest */ import mapValues from 'lodash/mapValues' -import { DateTime } from 'luxon' +import moment from 'moment-timezone' import next from './next' import parse from './parse' -const N = (pattern, fromDate = '2018-04-09T06:25') => - next(parse(pattern), DateTime.fromISO(fromDate, { zone: 'utc' })).toISO({ - includeOffset: false, - suppressMilliseconds: true, - suppressSeconds: true, - }) +const N = (pattern, fromDate = '2018-04-09T06:25') => { + const iso = next(parse(pattern), moment.utc(fromDate)).toISOString() + return iso.slice(0, iso.lastIndexOf(':')) +} describe('next()', () => { mapValues( diff --git a/@xen-orchestra/cron/src/parse.js b/@xen-orchestra/cron/src/parse.js index 9ee9569af..3e5c9a912 100644 --- a/@xen-orchestra/cron/src/parse.js +++ b/@xen-orchestra/cron/src/parse.js @@ -173,12 +173,7 @@ export default createParser({ { aliases: 'jan feb mar apr may jun jul aug sep oct nov dec'.split(' '), name: 'month', - range: [1, 12], - - // this function is applied to numeric entries (not steps) - // - // currently parse month 0-11 - post: value => value + 1, + range: [0, 11], }, { aliases: 'mon tue wen thu fri sat sun'.split(' '), diff --git a/@xen-orchestra/cron/src/parse.spec.js b/@xen-orchestra/cron/src/parse.spec.js index a09266ad4..508e6a095 100644 --- a/@xen-orchestra/cron/src/parse.spec.js +++ b/@xen-orchestra/cron/src/parse.spec.js @@ -8,16 +8,16 @@ describe('parse()', () => { minute: [0], hour: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dayOfMonth: [1, 11, 21, 31], - month: [1, 3, 5, 8, 11], + month: [0, 2, 4, 7, 10], }) }) it('correctly parse months', () => { expect(parse('* * * 0,11 *')).toEqual({ - month: [1, 12], + month: [0, 11], }) expect(parse('* * * jan,dec *')).toEqual({ - month: [1, 12], + month: [0, 11], }) }) diff --git a/yarn.lock b/yarn.lock index f679c8cd2..3c0740856 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4957,10 +4957,6 @@ ftp@~0.3.10: readable-stream "1.1.x" xregexp "2.0.0" -full-icu@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/full-icu/-/full-icu-1.2.0.tgz#6bd8bf565f696aab30df503de2d47b92d9f1046f" - function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -7518,12 +7514,6 @@ ltx@^2.5.0, ltx@^2.6.2: dependencies: inherits "^2.0.1" -luxon@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/luxon/-/luxon-0.5.2.tgz#80d93f8e8a30e3a5bafa1d05a464872920e08be1" - dependencies: - full-icu "^1.2.0" - make-dir@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51"