* Check whether a pre-parsed cron matches `date`, using a pre-built Intl.DateTimeFormat for TZ conversion. * Both `parsed` and `fmt` should be created once outside any hot loop.
(parsed: _ParsedCronFields, date: Date, fmt: Intl.DateTimeFormat)
| 241 | * Both `parsed` and `fmt` should be created once outside any hot loop. |
| 242 | */ |
| 243 | function _cronMatchesParsed(parsed: _ParsedCronFields, date: Date, fmt: Intl.DateTimeFormat): boolean { |
| 244 | let minute: number, hour: number, dom: number, month: number, dow: number, year: number |
| 245 | try { |
| 246 | const parts = fmt.formatToParts(date) |
| 247 | const get = (type: string) => parseInt(parts.find((p) => p.type === type)?.value ?? '0', 10) |
| 248 | const weekdayStr = parts.find((p) => p.type === 'weekday')?.value ?? 'Sun' |
| 249 | minute = get('minute') |
| 250 | hour = get('hour') % 24 |
| 251 | dom = get('day') |
| 252 | month = get('month') |
| 253 | year = get('year') |
| 254 | dow = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].indexOf(weekdayStr) |
| 255 | if (dow === -1) dow = date.getUTCDay() |
| 256 | } catch { |
| 257 | minute = date.getUTCMinutes() |
| 258 | hour = date.getUTCHours() |
| 259 | dom = date.getUTCDate() |
| 260 | month = date.getUTCMonth() + 1 |
| 261 | year = date.getUTCFullYear() |
| 262 | dow = date.getUTCDay() |
| 263 | } |
| 264 | // Last day of the (TZ-local) month: `new Date(year, month, 0)` rolls to the last day of `month` |
| 265 | // because day 0 of the next month equals the last day of the current month. |
| 266 | const lastDay = new Date(year, month, 0).getDate() |
| 267 | const dowMatches = _matchCronField(parsed.dowField, dow, 0) || (dow === 0 && _matchCronField(parsed.dowField, 7, 0)) |
| 268 | return ( |
| 269 | _matchCronField(parsed.minuteField, minute, 0) && |
| 270 | _matchCronField(parsed.hourField, hour, 0) && |
| 271 | _matchDomField(parsed.domField, dom, lastDay) && |
| 272 | _matchCronField(parsed.monthField, month, 1) && |
| 273 | dowMatches |
| 274 | ) |
| 275 | } |
| 276 | |
| 277 | /** |
| 278 | * Computes the next Date after `after` (defaults to now) when the cron expression will fire. |
no test coverage detected