Вычисление времени между другими временными пространствами
Описание: В html таблице у меня есть:
- 2 столбца с данными для ввода: ( примерные значения вставляются в пример, вы должны ввести их сами, чтобы скрипт работал )
а) пуск, // пользователь вводит это поле
б) конец. (информация: end должен быть больше start, чтобы он работал правильно) // пользователь вводит это поле
- 4 столбца с данными, которые вычисляются / являются постоянными: (теперь это работает)
а) фактический (конец-начало),
б) нормативный (const, в примере 8:00, на практике по-разному)
в) сверхурочные ( = |нормативно - фактическое | (&ГТ;=0) ) // если фактический(> в)нормативные
д) tobeworkout ( = |нормативно - фактическое | (=&ЛТ;0) ) // если фактический(&ЛТ;)нормативных
- 2 столбца с данными, которые я пытаюсь вычислить: (чего я пытаюсь достичь)
а) overtime_days, ( если фактическое>нормативное, то: если начало и конец (рабочее время) находятся между 6:00(>=) и 22:00(=<), то: overtime_days = фактическое-нормативное )
б) overtime_night ( если фактическое&ГТ;нормативно потом: если начало и конец (время работы) находится в диапазоне от 0:00 до 6:00(&ЛТ;) и 22:00 (и GT;) до 23:59 то: overtime_days = фактический-нормативный )
записи:
необходимо рассмотреть случай, когда, например, он начинается в 5:00 и заканчивается в 20:00, тогда учитываются ночные и сверхурочные, а также дневные сверхурочные: нормативные = 8:00, с 5:00 до 6:00 = 1:00 overtime_night и с 6:00 до 14:00 нормативные, с 14:00 до 20:00 overtime_days
Код: (код не включает вычисления для искомых значений)
const actuals = [...document.getElementsByClassName("actual")]; const normative = [...document.getElementsByClassName("normative")]; document.querySelector('table').addEventListener('change', function (e) { const classList = e.target.classList; if (classList.contains('start') || classList.contains('end')) { const tr = e.target.parentNode.parentNode; const [start, end, actual] = [...tr.querySelectorAll('.start,.end,.actual')]; const value = diff(start.value, end.value); actual.value = value; //here is the actual sum counting, please do not deal with it (sum field dont exist in this example) updateActualSum(); } }); document.querySelector('table').addEventListener('change', function (e) { const classList = e.target.classList; if (classList.contains('start') || classList.contains('end')) { const tr = e.target.parentNode.parentNode; const [actual, normative, overtime, tobeworkout] = [...tr.querySelectorAll('.actual,.normative,.overtime,.tobeworkout')]; if (diffMs(actual.value, normative.value) >= 0) { overtime.value = diff(normative.value, actual.value); tobeworkout.value = "00:00"; } if (diffMs(actual.value, normative.value) <= 0) { tobeworkout.value = diff(actual.value, normative.value); overtime.value = "00:00"; } } }); // this function calculate a difference for a logical purposes function diffMs(start, end) { return +start.split(":").join('') - +end.split(":").join(''); } // Update total duration once on load updateActualSum(); function msToTime(duration) { const minutes = Math.floor((duration / (1000 * 60)) % 60), hours = Math.floor(duration / (1000 * 60 * 60)); return twoOrMoreDigits(hours) + ":" + twoOrMoreDigits(minutes); } function twoOrMoreDigits(n) { return n < 10 ? '0' + n : n; } function timeToMs(time) { if (time) { // may be "" if the value is not set const [hours, minutes] = time.split(":").map(str => parseInt(str, 10)); return (hours * 60 + minutes) * 60 * 1000; } return 0; } function sum_diff() { const sum = actuals.reduce((acc, el) => acc + timeToMs(el.value), 0); return msToTime(sum); } function diff(start, end) { return msToTime(timeToMs(end) - timeToMs(start)); } function updateActualSum() { document.getElementById('id_sum_actual').value = sum_diff(); } <!-- language: lang-html --> <table> <thead> <tr> <th>start</th> <th>end</th> <th>actual</th> <th>normative</th> <th>overtime</th> <th>tobeworkout</th> <th>overtime_days</th> <th>overtime_night</th> </tr> </thead> <tbody> <tr class="day"> <td><input type="time" class="start" id="start_1" value="08:00"></td> <td><input type="time" class="end" id="end_1" value="15:00"></td> <td><input type="time" class="actual" id="actual_1" value="07:00" readonly></td> <td><input type="time" class="normative" id="normative_1" value="08:00" readonly></td> <td><input type="time" class="overtime" id="overtime_1" value="00:00" readonly></td> <td><input type="time" class="tobeworkout" id="tobeworkout_1" value="00:00" readonly></td> <td><input type="time" class="overtime_days" id="overtime_days_1" value="00:00" readonly></td> <td><input type="time" class="overtime_night" id="overtime_night_1" value="00:00" readonly></td> </tr> <tr class="day"> <td><input type="time" class="start" id="start_2" value="08:00"></td> <td><input type="time" class="end" id="end_2" value="17:00"></td> <td><input type="time" class="actual" id="actual_2" value="09:00" readonly></td> <td><input type="time" class="normative" id="normative_2" value="08:00" readonly></td> <td><input type="time" class="overtime" id="overtime_2" value="00:00" readonly></td> <td><input type="time" class="tobeworkout" id="tobeworkout_2" value="00:00" readonly></td> <td><input type="time" class="overtime_days" id="overtime_days_2" value="00:00" readonly></td> <td><input type="time" class="overtime_night" id="overtime_night_2" value="00:00" readonly></td> </tr> </tbody> </table>
Что я уже пробовал:
I don't know how to catch time between start and end, I'm looking for ideas , because it's a hard topic for me
Richard MacCutchan
Используйте элемент управления DateTime, который позволяет пользователю выбирать время, а не вводить его. Затем вам понадобятся обработчики событий, чтобы проверить, что время действительно и конец больше, чем начало. Исходя из этого, вы должны легко найти часы в течение любого периода времени (день, вечер, ночь), как это определено в ваших правилах.