I'm developing a webpage displaying the scheduled pipelines from all projects of a GitLab instance. The scheduled time is expressed using CRON expressions, i.e. five digits as follows:
Because not all future users of my webpage are familiar with CRON expressions, I wrote a script for translating it into a human-readable time expression.
Some important information for understanding the logic behind the code:
- "7" is not used as an alias for "Sunday" on my GitLab instance.
- Timezones are not taken into account (...yet). I'm considering all CRON expressions as UTC times for now.
- Times are expressed in the 24 hours format (so 11:23PM is 23h23)
- The pipelines that we launch take a lot of time to be fully executed, which is why we don't allow the first digit of the CRON expression to be
*
.
Some examples of cron-to-string conversion:
0 4 * * * * → "Runs at 04h00 every day"
0 23 * * 0 → "Runs at 23h00 on Sundays"
0 4 1 * * → "Runs at 04h00 on the 1st day of every month"
The code
function convertCronToString(cronExpression) {
var cron = cronExpression.split(" ");
var minutes = cron[0];
var hours = cron[1];
var dayOfMonth = cron[2];
var month = cron[3];
var dayOfWeek = cron[4];
var cronToString = "Runs at ";
// Formatting time if composed of zeros
if (minutes === "0") minutes = "00";
if (hours === "0") hours = "00";
// If it's not past noon add a zero before the hour to make it look like "04h00" instead of "4h00"
else if (hours.length === 1 && hours !== "*") {
hours = "0" + hours;
}
// Our activities do not allow launching pipelines every minute. It won't be processed.
if (minutes === "*") {
cronToString =
"Unreadable cron format. Cron will be displayed in its raw form: " +
cronExpression;
}
cronToString = cronToString + hours + "h" + minutes + " ";
if (dayOfWeek === "0,6") dayOfWeek = "on weekends";
else if (dayOfWeek === "1-5") dayOfWeek = "on weekdays";
else if (dayOfWeek.length === 1) {
if (dayOfWeek === "*" && dayOfMonth === "*") dayOfWeek = "every day ";
else if (dayOfWeek === "*" && dayOfMonth !== "*") {
cronToString = cronToString + "on the " + dayOfMonth;
if (
dayOfMonth === "1" ||
dayOfMonth === "21" ||
dayOfMonth === "31"
) {
cronToString = cronToString + "st ";
} else if (dayOfMonth === "2" || dayOfMonth === "22") {
cronToString = cronToString + "nd ";
} else if (dayOfMonth === "3" || dayOfMonth === "23") {
cronToString = cronToString + "rd ";
} else {
cronToString = cronToString + "th ";
}
cronToString = cronToString + "day of every month";
return cronToString;
} else if (dayOfWeek !== "*" && dayOfMonth === "*") {
switch (parseInt(dayOfWeek)) {
case 0:
dayOfWeek = "on Sundays";
break;
case 1:
dayOfWeek = "on Mondays";
break;
case 2:
dayOfWeek = "on Tuesdays";
break;
case 3:
dayOfWeek = "on Wednesdays";
break;
case 4:
dayOfWeek = "on Thursdays";
break;
case 5:
dayOfWeek = "on Fridays";
break;
case 6:
dayOfWeek = "on Saturdays";
break;
default:
cronToString =
"Unreadable cron format. Cron will be displayed in its raw form: " +
cronExpression;
return cronToString;
}
}
cronToString = cronToString + dayOfWeek + " ";
}
return cronToString;
}
Question
How could this code be optimized?
Additional information
- This method is part of a Vue.JS component so I apologize if I forgot to translate some of the Vue-specific into Vanilla Javascript.
- I have not implemented the code in case the pipeline is supposed to run on a given number of days of the week/month when provided as a suite of numbers separated by commas.
,
or-
indayOfWeek
, I looked up how these are formed. Does your code correctly handle0,30 0,12 1,8,15,22,29 1-12 *
? \$\endgroup\$ – Peilonrayz Feb 19 '19 at 12:29