我需要計算兩個日期時間之間的休假時間。由于這是一個假期(休假,PTO)應用程式,因此找到兩個日期時間之間經過的休假時間很重要。
休假時間以公司營業時間(9:00:00-18:00:00)休假的小時數來衡量。
例如 :
let start_at = '2021-12-27 14:00:00';
let end_at = '2021-12-28 14:00:00';
start_at - end_at1天內出結果。24小時。
我期望的結果是9小時,而不是 1 天。
如何計算不同的營業時間間隔(例如,9 小時塊)而不是實際時間范圍?
uj5u.com熱心網友回復:
首先,忽略小時數并計算兩個日期之間的天數差(忽略您指出的假期)。
2021-12-25 -> 2021-12-29 = 4 days difference. 將該數量乘以 9 小時,4 * 9 = 36 小時。
如果需要,您還可以對分鐘進行更多算術運算:
(14:25:00 start, 15:00:00 end, would mean you do 36 - (25/60))
然后,當您想顯示用戶將小時數除以 9 的“天數”時,請確保將小數點轉換為分鐘數。
uj5u.com熱心網友回復:
這不像獲取兩個日期之間的時間那么簡單。
您需要確定開始時間是在開始日期的營業時間之前、之中還是之后,然后計算出當天的營業時間。
然后計算出直到最后一天(但不包括最后一天)的每一天的營業時間。
然后與第一天類似地計算最后一天的營業時間,除了您希望結束日期之前而不是之后的小時數。
結果將是第一天的小時數 中間小時數 最后一天的小時數,以天數和小時數表示。
下面是一個相當簡單的實作,它的作業時間是周一到周五的 8 到 17 點。目的不是為 OP 的要求提供可靠的解決方案,而是解釋所涉及的復雜性和問題。
// Return ISO week number as YYYY[W]WW, e.g. 2020W1
// https://stackoverflow.com/a/6117889/257182
function getWeekNumber(d) {
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
d.setUTCDate(d.getUTCDate() 4 - (d.getUTCDay()||7));
var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
var weekNo = Math.ceil((((d - yearStart) / 86400000) 1) / 7);
return `${d.getUTCFullYear()}W${('' weekNo).padStart(2,'0')}`;
}
// Assume business days are Monday to Friday
// If start time is not 00:00:00, count from start of next day
// If end time is not 00:00:00, count to start of day
// Part days must be handled by caller
function getWholeBusinessDays(start, end) {
// end must be >= start
if (end < start) return;
// Helper - set Sat or Sun to Mon
let setToMon = d => d.setDate(d.getDate() (d.getDay() == 6? 2 : 1));
let s = new Date( start),
e = new Date( end),
days = 0;
// If s doesn't start at midnight, set to end of day
if (s.setHours(0,0,0,0) != start) s.setHours(24);
// Set e to start of day
e.setHours(0,0,0,0);
// If s is on a weekend, set to Monday
if (!(s.getDay() % 6)) setToMon(s);
// If e is on a weekend, set to Monday
if (!(e.getDay() % 6)) setToMon(e);
// If s and e are same week, get days between them
if (getWeekNumber(s) == getWeekNumber(e)) {
return e.getDay() - s.getDay();
// Otherwise get days from s to end of week
// days from start of week to e 5 * weeks between
} else {
days = 6 - s.getDay() e.getDay() - 1;
weeks = (Math.floor((e - s) / (7 * 8.64e7)));
// If s.weekday on or before e.weekday, have too many weeks
if (s.getDay() <= e.getDay()) --weeks;
// Add weeks to days
days = weeks * 5;
}
return days;
}
// Get leave as [days, hours] between two dates
// Business hours are 8 to 17 Mon to Fri
// Only whole hours considered
// If start or end day hours not zero, only business hours on that day are counted
// If end day is 00:00, counts as whole day (i.e. inclusive)
function getLeave(start, end) {
// end must be >= start
if (end < start) return;
// Helper - set Sat or Sun to Mon
let setToMon = d => d.setDate(d.getDate() (d.getDay() == 6? 2 : 1));
let setToDayStart = d => d.setHours(0,0,0,0);
let setToDayEnd = d => d.setHours(24,0,0,0);
// Setup
let s = new Date( start),
e = new Date( end),
hours = 0,
days = 0;
// Move weekends to start of Monday
if (!(s.getDay() %6)) {
setToMon(s);
setToDayStart(s);
}
if (!(e.getDay() %6)) {
setToMon(e);
setToDayStart(e);
}
// If start not 00:00, get hours and set to next day
if (s.getHours()) {
if (s.getHours() < 8) {
s.setHours(8);
}
if (s.getHours() < 17) {
hours = 17 - s.getHours();
}
// Accounted for start day hours so set to next day
setToDayEnd(s);
}
// If end not 00:00, get hours and set to start of day
if (e.getHours() > 17) {
e.setHours(17);
}
if (e.getHours() > 8) {
hours = e.getHours() - 8;
}
setToDayStart(e);
// If hours are more than 9, add excess to days
if (hours > 8) {
days = Math.floor(hours / 9);
hours = hours % 9;
}
// Add business days between dates
days = getWholeBusinessDays(s, e);
// If original end was a business day and 00:00,
// include it
if (end.getDay() % 6 && end.getHours() == 0) {
days;
}
return [days, hours];
}
// Examples
[[new Date(2022,0, 3, 0), new Date(2022,0, 3, 0)], // Mon to Mon 1 day
[new Date(2022,0, 3, 0), new Date(2022,0, 4,12)], // Mon to Tue noon 1 day, 4 hours
[new Date(2022,0, 3, 0), new Date(2022,0, 4, 0)], // Mon to Tue 2 days
[new Date(2022,0, 7, 0), new Date(2022,0,10, 0)], // Fri to Mon 2 days
[new Date(2022,0, 7,12), new Date(2022,0,10,12)], // Fri noon to Mon noon
[new Date(2022,0, 7,12), new Date(2022,0,17,12)], // Fri noon to Mon noon 1 week
[new Date(2022,0, 4, 0), new Date(2022,0, 6, 0)], // Tue to Thu 3 days
[new Date(2022,0, 6, 0), new Date(2022,0,18, 0)], // Thu to Tue week 9 days
].forEach(([s, e]) => {
let [days, hours] = getLeave(s, e);
console.log(`${s.toString().substr(0,21)} - ${e.toString().substr(0,21)} `
`${days} day${days == 1? '':'s'} ${hours} hour${hours == 1? '':'s'}`);
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/400080.html
標籤:javascript 约会时间
