MCPcopy Index your code
hub / github.com/FlowiseAI/Flowise / computeNextRunAt

Function computeNextRunAt

packages/server/src/services/schedule/utils.ts:289–351  ·  view source on GitHub ↗
(cronExpression: string, timezone: string = 'UTC', after?: Date)

Source from the content-addressed store, hash-verified

287 * to avoid repeated allocations on every iteration.
288 */
289export const computeNextRunAt = (cronExpression: string, timezone: string = 'UTC', after?: Date): Date | null => {
290 const fields = cronExpression.trim().split(/\s+/)
291 const hasSeconds = fields.length === 6
292
293 const start = new Date(after ? after.getTime() : Date.now())
294
295 // Hoist allocations outside the loop
296 const parsed = _parseCronFields(cronExpression)
297 const fmt = new Intl.DateTimeFormat('en-US', {
298 timeZone: timezone,
299 year: 'numeric',
300 month: 'numeric',
301 day: 'numeric',
302 hour: 'numeric',
303 minute: 'numeric',
304 weekday: 'short',
305 hour12: false
306 })
307
308 if (!hasSeconds) {
309 // ── 5-field cron: minute-level search ──────────────────────────────
310 start.setSeconds(0, 0)
311 start.setMinutes(start.getMinutes() + 1)
312
313 const maxIterations = 60 * 24 * 366 // up to ~1 year of minutes
314 for (let i = 0; i < maxIterations; i++) {
315 const candidate = new Date(start.getTime() + i * 60_000)
316 if (_cronMatchesParsed(parsed, candidate, fmt)) {
317 return candidate
318 }
319 }
320 return null
321 }
322
323 // ── 6-field cron: second-level search ──────────────────────────────────
324 const secondField = fields[0]
325
326 // Snap to the start of the next second
327 start.setMilliseconds(0)
328 start.setSeconds(start.getSeconds() + 1)
329
330 // Determine the first minute boundary and the second offset within it
331 const firstMinuteMs = start.getTime() - (start.getTime() % 60_000)
332 const firstSecondOffset = Math.round((start.getTime() - firstMinuteMs) / 1000)
333
334 const maxMinuteIterations = 60 * 24 * 366 // up to ~1 year of minutes
335 for (let i = 0; i < maxMinuteIterations; i++) {
336 const minuteMs = firstMinuteMs + i * 60_000
337 const minuteDate = new Date(minuteMs)
338
339 if (!_cronMatchesParsed(parsed, minuteDate, fmt)) continue
340
341 // This minute matches — find the first matching second
342 // For the first iteration, skip seconds before our start time
343 const secStart = i === 0 ? firstSecondOffset : 0
344 for (let s = secStart; s <= 59; s++) {
345 if (_matchCronField(secondField, s, 0)) {
346 return new Date(minuteMs + s * 1000)

Callers 3

createOrUpdateScheduleFunction · 0.90
updateScheduleAfterRunFunction · 0.90
utils.test.tsFile · 0.90

Calls 4

_parseCronFieldsFunction · 0.85
_cronMatchesParsedFunction · 0.85
_matchCronFieldFunction · 0.85
getTimeMethod · 0.45

Tested by

no test coverage detected