有效计算日期范围内的单个小时数



我想计算具有开始和结束时间的元素的每小时计数(或其他间隔(。

假设它是具有以下示例集的每小时间隔:

const sampleSet = [
{
start_date: "2020-06-01",
end_date: "2020-06-01",
start_time: "08:00",
end_time: "12:00"
},
{
start_date: "2020-06-01",
end_date: "2020-06-01",
start_time: "10:00",
end_time: "13:00"
}
];

最终结果如下所示:

const result = [
{
"2020-06-01 00:00": 0,
...
"2020-06-01 07:00": 0,
"2020-06-01 08:00": 1,
"2020-06-01 09:00": 1,
"2020-06-01 10:00": 2,
"2020-06-01 11:00": 2,
"2020-06-01 12:00": 2,
"2020-06-01 13:00": 1,
"2020-06-01 14:00": 0,
...
}
]

我知道我可以每小时循环一次并计算时间段内的所有元素,但这可能会以很多循环结束,尤其是当它的时间范围更长时。

我认为如果我循环访问元素并将它们分配给时间段会更好。例如,推送阵列插槽。

我会先将它们转换为时刻对象以便于修改:

const DATE_TIME_FORMAT = "YYYY-MM-DD hh:mm";
const formattedElements = sampleSet.map(element => ({
start: moment(element.start_date + " " + element.start_time, DATE_TIME_FORMAT),
end: moment(element.end_date + " " + element.end_time, DATE_TIME_FORMAT)
}));

但我现在不确定如何进行。

任何反馈将不胜感激!

首先循环时间范围。遇到每个新日期时,请检查是否有插槽,如果没有,请创建它们。然后为相关范围添加计数。

由于您只处理一种日期格式,因此只需要简单的解析和格式化函数,例如

// Parse timestamp in format YYYY-MM-DD HH:mm
function parse(s) {
let [Y, M, D, H, m] = s.split(/D/);
return new Date(Y, M-1, D, H||0, m||0);
}
// Format date as YYYY-MM-DD HH:mm
function format(d) {
let z = n => (n<10? '0':'') + n;
return d.getFullYear() + '-' + z(d.getMonth()+1) + '-' +
z(d.getDate()) + ' ' + z(d.getHours()) + ':' + z(d.getMinutes());
}
// Add slots given start date s, end date e, 
// interval i in minutes to object o
function addSlots(s, e, i, o) {
// Copy start and set to start of day
let d = new Date(s);
d.setHours(0,0,0,0);
// Store the end date
let t = e.getDate();
// Add slots from start to end
while (d.getDate() <= t) {
o[format(d)] = 0;
d.setMinutes(d.getMinutes() + i);
}
}
// Loop over elements, adding slots and counts for each element
// for interval i
function genSlotCounts(data, i) {
let slots = {};
data.forEach(obj => {
// Setup for loop
let start = parse(obj.start_date + ' ' + obj.start_time);
let end   =  parse(obj.end_date + ' ' + obj.end_time);
// Check for slots, add if missing
if (!slots.hasOwnProperty(format(start))) {
addSlots(start, end, i, slots);
}
// Loop over the range, incrementing on each loop, adding 1 to slot
while (start <= end) {
// Update slots
slots[format(start)] += 1;
start.setMinutes(start.getMinutes() + i);
}
});
return slots;
}
let data = [
{
start_date: "2020-06-01",
end_date: "2020-06-03",
start_time: "08:00",
end_time: "12:00"
},
{
start_date: "2020-06-01",
end_date: "2020-06-01",
start_time: "10:00",
end_time: "13:00"
},
{
start_date: "2020-06-02",
end_date: "2020-06-02",
start_time: "06:00",
end_time: "18:00"
},
{
start_date: "2020-06-02",
end_date: "2020-06-02",
start_time: "09:00",
end_time: "13:00"
},
{
start_date: "2020-06-02",
end_date: "2020-06-02",
start_time: "12:00",
end_time: "16:00"
}
];
let slots = genSlotCounts(data, 60);
console.log(slots);

上述问题仍然存在,例如覆盖现有插槽的可能性,如何处理一天结束时的午夜,如果间隔不是 24 小时的整数除数会发生什么,等等,但它应该让你继续。

相关内容

最新更新