A Pen by Christian Nunciato on CodePen.
Last active
October 6, 2018 16:36
-
-
Save cnunciato/1c982620a169da13678b80e6fd3a0510 to your computer and use it in GitHub Desktop.
Take a day off!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1>Take a Day Off!</h1> | |
<p> | |
Behold, a random selection of workdays for you to take off over the next year. | |
</p> | |
<p> | |
Now go do something fun with them! | |
</p> | |
<ol class="days"></ol> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const holidays = [ | |
[2018, 11, 12], // Veteran's Day (Observed) | |
[2018, 11, 22], // Thanksgiving Day | |
[2018, 11, 23], // Thanksgiving Day-After Day | |
[2018, 12, 25], // Christmas Day | |
[2019, 1, 1], // New Year's Day | |
[2019, 1, 15], // Martin Luther King, Jr., Day | |
[2019, 2, 18], // President's Day | |
[2019, 5, 27], // Memorial Day | |
[2019, 7, 4], // Independence Day | |
[2019, 9, 2], // Labor Day | |
[2019, 11, 11], // Veteran's Day | |
[2019, 11, 28], // Thanksgiving Day | |
[2019, 11, 29], // Thanksgiving Day-After Day | |
[2019, 12, 25] // Christmas Day | |
] | |
.map(d => new Date(d[0], d[1] - 1, [d[2]])); | |
const isHoliday = (date) => { | |
return holidays | |
.map(holiday => holiday.getTime()) | |
.includes(date.getTime()); | |
} | |
const isWeekend = (date) => { | |
return [0, 6].includes(date.getDay()); | |
} | |
const intoMonths = (acc, day) => { | |
const m = day.getMonth(); | |
acc[m] = [...(acc[m] || []), day]; | |
return acc; | |
}; | |
const intoFlattened = (acc, [firstDay, secondDay]) => { | |
return acc.concat(firstDay, secondDay); | |
}; | |
const intoHalves = (days) => { | |
const mid = days.length / 2; | |
return [days.slice(0, mid), days.slice(mid)]; | |
}; | |
const randomize = (items) => { | |
return items.sort(() => { | |
const randomCompare = Math.random() > Math.random(); | |
return randomCompare ? 1 : -1; | |
}); | |
}; | |
const oneDay = 24 * 60 * 60 * 1000; | |
const today = new Date().getTime(); | |
// Start with an array of 365 dates, beginning with today | |
const daysOff = new Array(365) | |
.fill(null) | |
.map((_, i) => new Date(new Date(today + (i * oneDay)).setHours(0, 0, 0, 0))) | |
// Strip out holidays and weekends | |
.filter(d => !isHoliday(d) && !isWeekend(d)) | |
// Group the remaining workdays into months | |
.reduce(intoMonths, []) | |
// Split each month into two arrays, one for the first half, one for the second | |
.map(intoHalves) | |
// Randomly select one day from each half of the month | |
.map(month => month.map(d => randomize(d))) | |
.map(([firstHalf, secondHalf]) => [...firstHalf.slice(-1), ...secondHalf.slice(-1)]) | |
// And finally, flatten, re-sort by date, and return the list | |
.reduce(intoFlattened, []) | |
.sort((a, b) => a < b ? -1 : 1); | |
// Enjoy! | |
document.addEventListener('DOMContentLoaded', () => { | |
const days$ = document.querySelector('.days'); | |
daysOff.forEach(day => { | |
const day$ = document.createElement('li'); | |
day$.innerText = day; | |
days$.appendChild(day$); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
font-family: Helvetica, sans-serif; | |
font-size: 14px; | |
line-height: 18px; | |
} | |
.date { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment