Last active
December 7, 2022 02:35
-
-
Save intrnl/2c195a5bd608952ba9e022c6c1b767ae to your computer and use it in GitHub Desktop.
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
// 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