-
Notifications
You must be signed in to change notification settings - Fork 0
/
addHolidays.html
125 lines (122 loc) · 5 KB
/
addHolidays.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.0/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.0/themes/base/jquery-ui.css" />
<script>
window.addEventListener("DOMContentLoaded", () => {
/* Holiday script for calendar
(c) 2010-2022 Michel Plungjan javascripts(a)plungjan.name
*/
Number.prototype.pad = function(n) { return String(this).padStart(n,"0")};
const Sun = 0, Mon = 1, Tue = 2, Wed = 3, Thu = 4, Fri = 5, Sat = 6;
const NthDay = (whatOffset, whichDay, whichMonth, whichYear) => {
// examples - whichDay is Sun=0 to Sat=6:
// 3rd Monday in January 2010: (3,1,1,2010); // Martin Luther King day 2010
// 3rd Monday In February, current year (3,1,2); // Washington Day
// Last Friday In April (-1,5,4); // National Arbor Day
let d = new Date();
if (whichYear) d.setFullYear(whichYear);
if (whatOffset != -1) {
d.setMonth(whichMonth - 1, 1, 0, 0, 0, 0); // first of the month, normalised;
while (d.getDay() != whichDay) d.setDate(d.getDate() + 1);
d.setDate(d.getDate() + ((whatOffset - 1) * 7))
} else {
d.setMonth(d.getMonth() + 1, 0, 0, 0, 0); // last of the month, normalised;
while (d.getDay() != whichDay) d.setDate(d.getDate() - 1);
}
console.log(d.toLocaleDateString())
return (d.getMonth() + 1).pad(2) + '/' + d.getDate().pad(2);
}
/* Easter Calculation by Stephen Chapman http://www.felgall.com March 2007
("Meeus/Jones/Butcher Gregorian algorithm".) */
const easter = (year) => {
let a = year % 19;
let b = Math.floor(year / 100);
let c = year % 100;
let d = Math.floor(b / 4);
let e = b % 4;
let f = Math.floor((b + 8) / 25);
let g = Math.floor((b - f + 1) / 3);
let h = (19 * a + b - d - g + 15) % 30;
let i = Math.floor(c / 4);
let j = c % 4;
let k = (32 + 2 * e + 2 * i - h - j) % 7;
let m = Math.floor((a + 11 * h + 22 * k) / 451);
let month = Math.floor((h + k - 7 * m + 114) / 31);
let day = ((h + k - 7 * m + 114) % 31) + 1;
return [3, 4][month - 3].pad(2) + '/' + day.pad(2);
}
const yearMaps = [];
const getVariableHoliday = (dateString, year) => {
if (!yearMaps[year]) {
yearMaps[year] = [];
for (let o in variableHolidayMap) {
let varHolString = eval('NthDay(' + variableHolidayMap[o] + ',' + year + ')');
// console.log(o + ':' + varHolString)
yearMaps[year][varHolString] = o;
}
}
return yearMaps[year][dateString];
}
const fixedHolidayMap = { // "Name of day":"MM/DD"
"New years Day": "01/01",
"Groundhog Day": "02/02",
"Valentine's Day": "02/14",
"Earth Day": "04/22",
"Flag Day": "06/14",
"Independence Day": "07/04",
"Halloween": "10/31",
"Veterans Day": "11/11",
"Pearl Harbor Remembrance Day": "12/07",
"Christmas Day": "12/25"
}
const variableHolidayMap = { // "Name of day":"Nth,DDD,M"
"Martin Luther King Day": "3,Mon,1", // 3rd Mon in Jan
"Washington's Birthday": "3,Mon,2", // 3rd Mon in Feb
"National Arbor Day": "-1,Fri,4", // Last Fri of Apr
"Mother's Day": "2,Sun,5", // 2nd Sun in May
"Memorial Day": "-1,Mon,5", // Last Mon of May
"Father's Day": "3,Sun,6", // 3rd Sun in Jun
"Labor Day": "1,Mon,9", // 1st Mon in Sep
"Columbus Day": "2,Mon,10", // 2nd Mon in Oct
"Thanksgiving Day": "4,Thu,11" // 4th Thu in Nov
};
const availableTags = ["Easter"]; // the odd one out
const fixedHoliday = [];
for (let o in fixedHolidayMap) { // build a holiday by dateString
availableTags[availableTags.length] = o;
fixedHoliday[fixedHolidayMap[o]] = o;
}
for (let o in variableHolidayMap) availableTags[availableTags.length] = o;
const holidayDate = document.getElementById("holidayDate");
const tags = document.getElementById("tags");
const tagList = document.getElementById("tagList");
tagList.innerHTML = availableTags.map(tag => `<option value="${tag}" />`).join("");
tags.addEventListener("change", function() {
let res = "";
let thisYear = new Date().getFullYear();
let val = this.value;
if (fixedHolidayMap[val]) res = fixedHolidayMap[val];
else if (val == "Easter") res = easter(thisYear);
else if (variableHolidayMap[val]) res = eval('NthDay(' + variableHolidayMap[val] + ',' + thisYear + ')')
if (res) res += '/' + thisYear;
const date = new Date(res)
date.setHours(15,0,0,0); // normalise
holidayDate.valueAsDate = date;
});
holidayDate.addEventListener("input", function() {
let date = this.valueAsDate;
let year = date.getFullYear();
let dateString = `${(date.getMonth()+1).pad(2)}/${date.getDate().pad(2)}`;
let res = "";
if (fixedHoliday[dateString]) res = fixedHoliday[dateString]
else if (dateString == easter(year)) res = "Easter";
else {
var holiday = getVariableHoliday(dateString, year);
if (holiday) res = holiday;
}
tags.value = res;
});
});
</script>
<input id="holidayDate" type="text" />
<input id="tags" />