It’s a bit complex, but here’s how I imagine it would work.
- Add a user-specific column called “year” that would serve as your “Year selector”. Say you want to view 2024 days for a specific user, you choose 2024 (meaning all vacation days from 1st May, 2024 to 30th April, 2025).
- Give choice options ranging from year X to current year (e.g: 2019 to 2024).
- Calculate two things below with math column:
S*10^4 + 5*10^2 + 1
with S being the selected year. You would get 20240501 if you chose 2024. This is the “start date”.
(S+1)*10^4 + 4*10^2 + 30
. You would get 20250430 if you chose 2024. This is the “end date”.
- Go to your vacation days logs table. I expect it to have a start date and end date as well, e.g:
User ID |
Vacation |
Start Date |
End Date |
U001 |
Vacation to Bahamas |
2024-04-29 |
2024-05-05 |
U002 |
Vacation to Mexico |
2024-07-07 |
2024-07-14 |
U002 |
Sick day |
2025-03-05 |
2025-03-05 |
U003 |
Vacation to Vietnam |
2025-04-26 |
2025-05-10 |
Then, calculate “Start Filter” and “End Filter” with the formulas below:
“Start Filter”: MAX(YEAR(VS)*10^4+MONTH(VS)*10^2+DAY(VS),SF)
With VS being the vacation’s start date, SF being the “start filter” we already pre-calculated.
“End Filter”: MIN(YEAR(VE)*10^4+MONTH(VE)*10^2+DAY(VE),EF)
With VE being the vacation’s start date, EF being the “end filter” we already pre-calculated.
It looks like this at this point:
User ID |
Vacation |
Start Date |
End Date |
Start Calculated |
End Calculated |
U001 |
Vacation to Bahamas |
2024-04-29 |
2024-05-05 |
20240501 |
20240505 |
U002 |
Vacation to Mexico |
2024-07-07 |
2024-07-14 |
20240707 |
20240714 |
U002 |
Sick day |
2025-03-05 |
2025-03-05 |
20250305 |
20250305 |
U003 |
Vacation to Vietnam |
2025-04-26 |
2025-05-10 |
20250426 |
20250430 |
Finally, I have to use JavaScript here to calculate the difference in days between two numbers, excluding weekends.
function calculateDateDifference(startDateNum, endDateNum) {
const parseToUtcDate = (yyyymmdd) => {
const s = String(yyyymmdd);
const year = parseInt(s.substring(0, 4), 10);
const month = parseInt(s.substring(4, 6), 10) - 1;
const day = parseInt(s.substring(6, 8), 10);
return new Date(Date.UTC(year, month, day));
};
if (startDateNum === endDateNum) {
return 1;
}
let d1 = parseToUtcDate(startDateNum);
let d2 = parseToUtcDate(endDateNum);
let currentDate, targetDate;
if (d1.getTime() <= d2.getTime()) {
currentDate = new Date(d1.getTime()); // Clone
targetDate = d2;
} else {
currentDate = new Date(d2.getTime()); // Clone
targetDate = d1;
}
let weekdayCount = 0;
const oneDayInMs = 24 * 60 * 60 * 1000;
while (currentDate.getTime() <= targetDate.getTime()) {
const dayOfWeek = currentDate.getUTCDay(); // 0 (Sunday) to 6 (Saturday)
if (dayOfWeek !== 0 && dayOfWeek !== 6) { // If not Sunday or Saturday
weekdayCount++;
}
currentDate.setTime(currentDate.getTime() + oneDayInMs);
}
return weekdayCount;
}
return calculateDateDifference(p1, p2)