Skip to content

Instantly share code, notes, and snippets.

@cnunciato
Last active October 6, 2018 16:36
Show Gist options
  • Save cnunciato/1c982620a169da13678b80e6fd3a0510 to your computer and use it in GitHub Desktop.
Save cnunciato/1c982620a169da13678b80e6fd3a0510 to your computer and use it in GitHub Desktop.
Take a day off!
<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>
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$);
});
});
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