Skip to content

Instantly share code, notes, and snippets.

@intrnl
Last active December 7, 2022 02:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save intrnl/2c195a5bd608952ba9e022c6c1b767ae to your computer and use it in GitHub Desktop.
Save intrnl/2c195a5bd608952ba9e022c6c1b767ae to your computer and use it in GitHub Desktop.
// This attendance counting function assumes the following:
// - You can attend multiple times in one day (and still be counted as one)
// - Attendance time is not counted, you can attend for several minutes and it still counts as one day
/** @typedef {string | number | Date} DateLike */
/**
* @param {Array<{ start: DateLike, end: DateLike }>} attendances
* @param {Date} startDate
* @param {Date} endDate
* @returns {{ total: number, attended: number, absent: number }}
*/
function countAttendances (attendances, startDate, endDate) {
let attended = 0;
let total = 0;
let days = new Set();
let date = new Date(startDate);
for (let idx = 0, len = attendances.length; idx < len; idx++) {
let attendance = attendances[idx];
let start = new Date(attendance.start);
let end = new Date(attendance.end);
// if it starts after the end date, or ends before the start date,
// they're outside the period we're looking for
if (start > endDate || end < startDate) {
continue;
}
// if it starts before the start date, cap it
if (start < startDate) {
start.setTime(startDate.getTime());
}
// if it ends after the end date, cap it
if (end > endDate) {
end.setTime(endDate.getTime());
}
// normalize the hours as we only want to count the days
start.setHours(0, 0, 0, 0);
while (start <= end) {
let time = start.getTime();
if (!days.has(time)) {
attended++;
days.add(time);
}
start.setDate(start.getDate() + 1);
}
}
// count the number of days in a given period
date.setHours(0, 0, 0, 0);
while (date <= endDate) {
total++;
date.setDate(date.getDate() + 1);
}
return {
total: total,
attended: attended,
absent: total - attended,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment