I'm writing a script that's changing the background color depending on hour of day, if it is a weekend or if it is a Swedish holiday. I have a functional script and as I want to improve my programming skills I want to see if there's anything I can do differently or more efficiently.
I wanted to work with separate functions to (hopefully) improve readability and make the script more adaptable by passing parameters. The script also runs a function on an interval to update the background color if the allowed time span has been passed. My concern is that this will affect performance as far as I know it will not be too CPU intensive.
closedDates();
function closedDates() {
//Create new date object
var d = new Date();
var year = d.getFullYear();
var closedDates = (calculateClosedDates(year));
var closedDates = [
new Date(year, 0, 1), // Fixed date: New Years day
new Date(year, 0, 5), // Fixed date: Twelfth Night
new Date(year, 0, 6), // Fixed date: Epiphany
new Date(closedDates[0]), // Thursday
new Date(closedDates[1]), // Good Friday
new Date(closedDates[2]), // Easter Day
new Date(closedDates[3]), // Easter Monday
new Date(year, 3, 30), // Fixed date: Walpurgis Night
new Date(year, 4, 1), // Fixed date: International Workers' Day
new Date(closedDates[4]), // Feast of the Ascension
new Date(closedDates[5]), // Pingstafton
new Date(closedDates[6]), // Pingstdagen
new Date(year, 5, 6), // Fixed date: Swedish National Day
new Date(closedDates[7]), // Saint John's Eve
new Date(closedDates[8]), // Midsummer day
new Date(closedDates[9]), // All Saints' Eve
new Date(closedDates[10]), // All Saints' Day
new Date(year, 11, 24), // Fixed date: Christmas Eve
new Date(year, 11, 25), // Fixed date: Christmas Day
new Date(year, 11, 26), // Fixed date: Christmas Eve
new Date(year, 11, 31) // Fixed date: New Years Eve
];
// Pass current date and date array to function
checkDate(d, closedDates);
}
function checkDate(d, closedDates) {
var openingHour = 10,
closingHour = 18,
weekend = [0, 6];
// Run check time once to see if it is open
checkTime();
// Check if time falls in between time span and is not a weekend
// Change background color if/else
function checkTime() {
d = new Date()
console.log(d);
if (d.getHours() < openingHour || d.getHours() >= closingHour || d.getDay() === weekend[0] || d.getDay() === weekend[1]) {
document.body.style.backgroundColor = "red";
}
else {
document.body.style.backgroundColor = "green";
}
}
// Check if current date is equal to a date in the date array
// Converting to time to be able to compare
// Change background colour accordingly
for (i = 0; i < closedDates.length; i++) {
if (d.getTime() === closedDates[i].getTime()) {
document.body.style.backgroundColor = "red";
return
}
else {
// Run script in 30 second intervals to update background reguraly
setInterval(checkTime, 30000);
return
}
}
}
function calculateClosedDates(year) {
/* This function calculates and returns an array with date objects of Swedish public holidays
Many days are based on when easterDay occurs and therefore I use
Gauss Easter Algorithm to calculate when easter day occurs for the current year.
It uses constanst M & N that needs to be updated 2099 but this is a non issue.
I could include a function that checks which year it is and updates the constants
accordingly but I feel it's over ambitious for this script.
Some days are fixed dates and some holidays shift and therefore need to be calculated
*/
// Start Gauss Easter Algorithm
// https://en.wikipedia.org/wiki/Computus#Gauss's_Easter_algorithm
// Constants, update year 2099 ;)
var M = 24,
N = 5,
a = year % 19,
b = year % 4,
c = year % 7,
d = ((19*a) + M) % 30,
e = ((2*b) + (4*c) + (6*d) + N) % 7,
easterDay = 22 + d + e,
// Easter Month as default March
easterMonth = 2;
// If easterDay is greater than 31, take value minus 31
// Set month to April
if (easterDay > 31) {
easterDay = easterDay - 31;
easterMonth = 3;
}
// Exceptions to formula
// If easterDay is 26 and easterMonth is April
// set date a week earlier
if (easterDay == 26 && easterMonth == 4) {
easterDay = easterDay - 7;
}
// If easterDay is 25, easterMonth is April, d is 28, e is 6 and a is greater than 10
// set date a week earlier
if (easterDay == 25 && easterMonth == 4 && d == 28 && e == 6 && a > 10) {
easterDay = easterDay - 7;
}
// End Gauss Easter Formula
var maundyThursday = new Date(year, easterMonth, easterDay-3), // Will always occur on the first thursday before easter day
goodFriday = new Date(year, easterMonth, easterDay-2), // Will always occur on the first friday before easter day
easter = new Date(year, easterMonth, easterDay), // Value from Gauss
easterMonday = new Date(year, easterMonth, easterDay+1), // Will always occur on the first monday after easter day
ascension = new Date(year, easterMonth, ((easterDay+4) + 35)), // Get the next thursday from easter day + 35 days (5 weeks)
pingstAfton = new Date(year, easterMonth, easterDay+48), // 7 Weeks - 1 day after easter day
pingstDagen = new Date(year, easterMonth, easterDay+49), // 7 Weeks after easter day
midsommarAfton = getSpecificDay(5, new Date(year, 5, 20)), // From start date, find first friday
midsommarDagen = getSpecificDay(6, new Date(year, 5, 20)), // From start date, find first saturday
allSaintsEve = getSpecificDay(5, new Date(year, 9, 30)), // From start date, find first friday
allSaintsDay = getSpecificDay(6, new Date(year, 9, 31)); // From start date, find first saturday
function getSpecificDay(holiday, startDate) {
// Get which specific day that the holiday (friday, saturday) is and then get the start date of the period
var calculatedDate = startDate;
calculatedDate.setDate(startDate.getDate() + (holiday - startDate.getDay() % 7));
return calculatedDate;
}
return [maundyThursday, goodFriday, easter, easterMonday, ascension, pingstAfton, pingstDagen, midsommarAfton, midsommarDagen, allSaintsEve, allSaintsDay];
}