Desc: In the html table I have:
2 columns with data to enter: ( sample values are inserted in the example, you must enter it yourself for the script to work )
a) start, // the user enters this field
b) end. (info: end must be larger than start for it to work properly) // the user enters this field
4 columns with data that are calculated / are constant: (now it is working)
a) actual (end-start),
b) normative (const, in example 8:00, in practice differently)
c) overtime ( = |normative - actual | (>=0) ) // if actual(>)normative
d) tobeworkout ( = |normative - actual | (=<0) ) // if actual(<)normative
2 columns with data that I am trying to calculate: (what I trying to achieve)
a) overtime_days, ( if actual>normative then: if start and end (work time) is between 6:00(>=) and 22:00(=<) then: overtime_days = actual-normative )
b) overtime_night ( if actual>normative then: if start and end (work time) is between 0:00 to 6:00(<) and 22:00(>) to 23:59 then: overtime_days = actual-normative )
notes:
it is necessary to consider the case when e.g. it starts at 5:00 and ends at 20:00, then night and overtime and daytime overtime are counted: normative = 8:00, from 5:00 to 6:00 = 1:00 overtime_night, and 6:00 to 14:00 normative, 14:00 to 20:00 overtime_days
What I did?
- 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
Code: (the code does not include calculations for the searched values)
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;
}
});
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('');
}
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 diff(start, end) {
return msToTime(timeToMs(end) - timeToMs(start));
}
<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>
Notes:
Please do not change the code I have already written.
The code is in partialView, partialView refreshes after changing options on dropdownbox (selectbox).
I use asp.net /net core 3.0
Changes: !!!!
This has changed:
if it has normative = 08: 00 and actual = 08: 00,
but he worked from 04:00 to 12:00 (at night from 04:00 to 6:00)
- he should count 02:00 hours as night hours ( at night from 22:00 to 6:00)
as if he worked from 15:00 to 23:00 (at night from 22:00 to 23:00)
- this should count 'overtime_night' / 'additional_nigth' as 01:00 ( at night from 22:00 to 6:00)