Вы можете сгруппировать длительности по онлайн / офлайн и уменьшить значения, чтобы получить общее количество.
Отображаемое время отображается в формате ЧЧ: ММ: СС, а длительности указаны в миллисекундах.
Если вы заметили, мои временные интервалы основаны на последовательности Фибоначчи, за исключением 01:00 и 01:30, потому что мне нужно было различать их.
Когда текущий вход в систему ОНЛАЙН, с тех пор пользователь находится в автономном режиме.
const main = () => {
let sessions = calculateSessions(logins);
Object.keys(sessions).forEach((key) => {
let duration = sessions[key].reduce((sum, ms) => sum + ms);
console.log(`Time spent ${key}: ${formatTime(duration)}`);
});
}
let logins = [
{ "id" : 1, "timestamp" : "2020-03-23T00:00:00.000Z", "online" : true },
{ "id" : 2, "timestamp" : "2020-03-23T01:00:00.000Z", "online" : false },
{ "id" : 3, "timestamp" : "2020-03-23T01:30:00.000Z", "online" : true },
{ "id" : 4, "timestamp" : "2020-03-23T02:00:00.000Z", "online" : false },
{ "id" : 5, "timestamp" : "2020-03-23T03:00:00.000Z", "online" : true },
{ "id" : 6, "timestamp" : "2020-03-23T05:00:00.000Z", "online" : false },
{ "id" : 7, "timestamp" : "2020-03-23T08:00:00.000Z", "online" : true },
{ "id" : 9, "timestamp" : "2020-03-23T13:00:00.000Z", "online" : false },
{ "id" : 10, "timestamp" : "2020-03-23T21:00:00.000Z", "online" : true },
{ "id" : 12, "timestamp" : "2020-03-24T10:00:00.000Z", "online" : false },
{ "id" : 13, "timestamp" : "2020-03-25T07:00:00.000Z", "online" : true }
];
// Assuming dates are pre-sorted and the online status is always staggered
const calculateSessions = (logins) => {
return logins.reduce((sessions, login, index, all) => {
if (index > 0) {
let duration = new Date(login.timestamp) - new Date(all[index - 1].timestamp);
sessions[login.online ? 'offline' : 'online'].push(duration);
}
return sessions;
}, { online : [], offline : [] });
};
const formatTime = (ms) => {
const pad = (n, z = 2) => ('00' + n).slice(-z);
const hh = pad(ms / 3.6e6 | 0);
const mm = pad((ms % 3.6e6) / 6e4 | 0);
const ss = pad((ms % 6e4) / 1000 | 0);
const mmm = pad(ms % 1000, 3);
return `${hh}:${mm}:${ss}.${mmm}`;
};
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }
Specifi c сценарий использования
const main = () => {
let details = calculateTimeOnline('Luna', logins);
console.log(Object.assign({}, details, {
totalTimeOnline : formatTime(details.totalTimeOnline)
}));
}
let logins = [
{ "id" : 1, "timestamp" : "2020-03-23T00:00:00.000Z", "online" : true },
{ "id" : 2, "timestamp" : "2020-03-23T01:00:00.000Z", "online" : false },
{ "id" : 3, "timestamp" : "2020-03-23T01:30:00.000Z", "online" : true },
{ "id" : 4, "timestamp" : "2020-03-23T02:00:00.000Z", "online" : false },
{ "id" : 5, "timestamp" : "2020-03-23T03:00:00.000Z", "online" : true },
{ "id" : 6, "timestamp" : "2020-03-23T05:00:00.000Z", "online" : false },
{ "id" : 7, "timestamp" : "2020-03-23T08:00:00.000Z", "online" : true },
{ "id" : 9, "timestamp" : "2020-03-23T13:00:00.000Z", "online" : false },
{ "id" : 10, "timestamp" : "2020-03-23T21:00:00.000Z", "online" : true },
{ "id" : 12, "timestamp" : "2020-03-24T10:00:00.000Z", "online" : false },
{ "id" : 13, "timestamp" : "2020-03-25T07:00:00.000Z", "online" : true }
];
// Assuming dates are pre-sorted and the online status is always staggered
const calculateTimeOnline = (user, logins) => {
return logins.reduce((result, login, index, all) => {
return index > 0 && !login.online
? Object.assign(result, {
totalTimeOnline : result.totalTimeOnline +
new Date(login.timestamp).getTime() -
new Date(all[index - 1].timestamp).getTime()
})
: result;
}, {
name: user,
totalTimeOnline: 0
});
};
const formatTime = (ms) => {
const pad = (n, z = 2) => ('00' + n).slice(-z);
const hh = pad(ms / 3.6e6 | 0);
const mm = pad((ms % 3.6e6) / 6e4 | 0);
const ss = pad((ms % 6e4) / 1000 | 0);
const mmm = pad(ms % 1000, 3);
return `${hh}:${mm}:${ss}.${mmm}`;
};
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }