#javascript #time
#javascript #время
Вопрос:
Мне нужна помощь в алгоритме вычисления времени. Это не обычная временная операция, поэтому momentjs здесь не поможет.
Короче говоря, у меня есть время, которое я хочу сократить на другое время, например:
120:30 // total time
- 1:30 // time 2
119:00 // result
Общее время — это расчетное время для задачи, используемой в моем приложении, поэтому оно не рассчитано на 24 часа. Время 2 является результатом рабочего времени, например, если бы я работал над этой задачей 2 раза, сначала 30 минут, а затем 60 минут, то есть полтора часа.
В моем алгоритме я могу суммировать общее рабочее время по минутам, но я не могу реализовать вычисление сокращения из самого общего времени.
Здесь идет мой код с прокомментированными частями:
// Types = 1- Start, 2- Stop
var estimatedTime = "120:30", // One hundred twenty hours and thirty minutes
timeHistory = [{
type: 1,
time: new Date(2016, 9, 10, 1, 0, 0) // Start action
}, {
type: 2,
time: new Date(2016, 9, 10, 1, 30, 0) // Adds 30 minutes since last history
}, {
type: 1,
time: new Date(2016, 9, 10, 1, 40, 0) // Start again after 10 minutes interval
}, {
type: 2,
time: new Date(2016, 9, 10, 2, 40, 0) // Adds 60 minutes since last history
}];
// Total of 90 minutes of work
//----------------------------------
// Calculation algorithm
var totalTime = 0,
lastTime = null;
timeHistory.forEach(function(h) {
// Sums to totalTime the diff between last "Start" and the current "Stop" time
if (lastTime amp;amp; h.type != 1) {
totalTime = h.time.getTime() - lastTime.getTime();
}
lastTime = h.time;
});
// If time is running (type 1 = Start), sums the current time
if (timeHistory[timeHistory.length - 1].type == 1) {
totalTime = (new Date()).getTime() - lastTime.getTime();
}
var t1 = Math.floor(totalTime / 60000); // Get total minutes
console.log(t1); // So far so good
var estTime = estimatedTime.split(":").map(Number), // Getting time hours and minutes as numbers
resultMinutes = 60 - (t1 % estTime[1]),
resultHours = (Math.floor(t1 / estTime[1]) > 0 ? (estTime[0] - Math.floor(t1 / estTime[1])) : 0);
if (resultMinutes == 60) {
resultHours = 1;
resultMinutes = 0;
}
console.log("Result:", resultHours ":" resultMinutes);
Как вы можете видеть, пока «Пока все хорошо» (строка 41), кажется, все работает нормально. Моя проблема с вычислением после этого. Это беспорядок, и я могу его развить. Результат в случае сниппета должен быть 119:00
. Любая помощь будет оценена.
Комментарии:
1. почему бы не использовать epoc для вычисления? а затем отображать часы и минуты?
2. @NinaScholz я не знаю этого или как это сделать.
3. Это фактическая дата? Или просто представление часа? Если позже вы просто выполните простую математику. И манипулирование строками.
4. @Darkrum всего час представления. Это может быть
1:00
на500:00
сегодняшний день само по себе не соответствует.5.
var s=(120*60 30 - (1*60 30)), M=Math.floor(s/60), S=M*60-s; [M,S]
Ответ №1:
Это можно было бы сделать проще, но поскольку это ваш код, и его важно изучить, я просто отредактировал и добавил еще несколько строк с комментариями. Надеюсь, это вам поможет.
// Types = 1- Start, 2- Stop
var estimatedTime = "120:30", // One hundred twenty hours and thirty minutes
timeHistory = [{
type: 1,
time: new Date(2016, 9, 10, 1, 0, 0) // Start action
}, {
type: 2,
time: new Date(2016, 9, 10, 1, 30, 0) // Adds 30 minutes since last history
}, {
type: 1,
time: new Date(2016, 9, 10, 1, 40, 0) // Start again after 10 minutes interval
}, {
type: 2,
time: new Date(2016, 9, 10, 2, 40, 0) // Adds 60 minutes since last history
}];
// Total of 90 minutes of work
//----------------------------------
// Calculation algorithm
var totalTime = 0,
lastTime = null;
timeHistory.forEach(function(h) {
// Sums to totalTime the diff between last "Start" and the current "Stop" time
if (lastTime amp;amp; h.type != 1) {
totalTime = h.time.getTime() - lastTime.getTime();
}
lastTime = h.time;
});
totalTimeInMins = totalTime/(1000*60); // Get total minutes of work done
console.log(totalTimeInMins " mins of work" );
var estTime = estimatedTime.split(":").map(Number); // Getting time hours and minutes as numbers
var estTimeInMins = estTime[0]*60 estTime[1] ;//converting esitmated time to minutes
var resultTimeInMins = estTimeInMins - totalTimeInMins ; //calculating result time
var resultHours = Math.floor(resultTimeInMins/60); //getting number of hours. Math.floor is rounding off to lower integer
var resultMinutes = resultTimeInMins%60; //calculating number of minutes. This is like getting the remainder.
console.log("Result:", resultHours ":" resultMinutes);
Комментарии:
1. Математика времени — это сука, я действительно не понимаю, ха-ха. Спасибо.
Ответ №2:
При манипулировании временем почти всегда рекомендуется делать это с точностью до миллисекунд.
var Time = (function () {
function Time(time) {
if (time === void 0) { time = 0; }
this.time = time;
}
Time.prototype.setSeconds = function (seconds) {
if (seconds === void 0) { seconds = 0; }
this.time = (seconds * 1000);
return this;
};
Time.prototype.setMinutes = function (minutes) {
if (minutes === void 0) { minutes = 0; }
this.time = ((minutes * 60) * 1000);
return this;
};
Time.prototype.setHours = function (hours) {
if (hours === void 0) { hours = 0; }
this.time = (((hours * 60) * 60) * 1000);
return this;
};
Time.prototype.setDays = function (days) {
if (days === void 0) { days = 0; }
this.time = ((((days * 24) * 60) * 60) * 1000);
return this;
};
Time.prototype.getTime = function (toString) {
if (toString === void 0) { toString = false; }
var t = this.time;
var d = new Date(Math.abs(t));
var sub = this.time < 0;
d.setHours(d.getHours() - 1);
d.setFullYear(0);
var time = {
days: Math.floor(Math.abs(this.time) / (((24 * 60) * 60) * 1000)),
hours: d.getHours(),
minutes: d.getMinutes(),
seconds: d.getSeconds(),
milliseconds: d.getMilliseconds(),
sub: sub
};
//Returns in the format "DAYS:HOURS:MINUTES:SECONDS"
if (toString === true) {
return (sub ? '-' : '')
Math.abs(time.days)
':'
Math.abs(time.hours)
':'
Math.abs(time.minutes)
":"
Math.abs(time.seconds);
}
else {
return time;
}
};
return Time;
}());
var t1 = new Time();
var t2 = new Time();
t1
.setMinutes(357)
.setHours(1200);
t2
.setHours(-1)
.setMinutes(-30);
var t3 = new Time(t1.time t2.time);
console.log("t1", t1.getTime(true));
console.log("t2", t2.getTime(true));
console.log("t3", t3.getTime(true));
console.log("t3", t3.getTime());
РЕДАКТИРОВАТЬ 1
Я забыл включить days
. В моей настройке дни масштабируются бесконечно (потому что я не хочу портить странные месяцы, такие как февраль или високосные годы).