obscreen/data/www/js/lib/is-cron-now.js
2024-05-21 20:35:46 +02:00

101 lines
3.7 KiB
JavaScript
Executable File

const cron = (() => {
const DAY_NAMES = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
const DAY_ABBRS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
const MINUTE_CHOICES = Array.from({length: 60}, (_, i) => [`${i}`, `${i}`]);
const HOUR_CHOICES = Array.from({length: 24}, (_, i) => [`${i}`, `${i}`]);
const DOM_CHOICES = Array.from({length: 31}, (_, i) => [`${i + 1}`, `${i + 1}`]);
const MONTH_CHOICES = Array.from({length: 12}, (_, i) => [`${i + 1}`, new Date(0, i).toLocaleString('en', { month: 'long' })]);
const DOW_CHOICES = DAY_NAMES.map((day, index) => [`${index}`, day]);
function toInt(value, allowDaynames = false) {
if (typeof value === 'number' || (typeof value === 'string' && !isNaN(value))) {
return parseInt(value, 10);
} else if (allowDaynames && typeof value === 'string') {
value = value.toLowerCase();
const dayIndex = DAY_NAMES.indexOf(value);
if (dayIndex !== -1) return dayIndex;
const abbrIndex = DAY_ABBRS.indexOf(value);
if (abbrIndex !== -1) return abbrIndex;
}
throw new Error('Failed to parse string to integer');
}
function parseArg(value, target, allowDaynames = false) {
value = value.trim();
if (value === '*') return true;
let values = value.split(',').map(v => v.trim()).filter(v => v);
for (let val of values) {
try {
if (toInt(val, allowDaynames) === target) {
return true;
}
} catch (error) {}
if (val.includes('-')) {
let step = 1;
let start, end;
if (val.includes('/')) {
[start, end] = val.split('-').map(part => part.trim());
[end, step] = end.split('/').map(part => toInt(part.trim(), allowDaynames));
start = toInt(start, allowDaynames);
} else {
[start, end] = val.split('-').map(part => toInt(part.trim(), allowDaynames));
}
for (let i = start; i <= end; i += step) {
if (i === target) return true;
}
if (allowDaynames && start > end) {
for (let i = start; i < start + 7; i += step) {
if (i % 7 === target) return true;
}
}
}
if (val.includes('/')) {
let [v, interval] = val.split('/').map(part => part.trim());
if (v !== '*') continue;
if (target % toInt(interval, allowDaynames) === 0) {
return true;
}
}
}
return false;
}
function hasBeen(s, since, dt = new Date()) {
since = new Date(since);
dt = new Date(dt);
if (dt < since) {
throw new Error("The 'since' datetime must be before the current datetime.");
}
while (since <= dt) {
if (isActive(s, since)) {
return true;
}
since = new Date(since.getTime() + 60000);
}
return false;
}
function isActive(s, dt = new Date()) {
let [minute, hour, dom, month, dow, year] = s.split(' ');
let weekday = dt.getDay();
return parseArg(minute, dt.getMinutes()) &&
parseArg(hour, dt.getHours()) &&
parseArg(dom, dt.getDate()) &&
parseArg(month, dt.getMonth() + 1) &&
parseArg(dow, weekday === 0 ? 6 : weekday - 1, true) &&
(!year || (year && parseArg(year, dt.getFullYear())));
}
return {
isActive
};
})();