Member 14713380 Ответов: 1

Вычисление времени между другими временными пространствами


Описание: В 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, который позволяет пользователю выбирать время, а не вводить его. Затем вам понадобятся обработчики событий, чтобы проверить, что время действительно и конец больше, чем начало. Исходя из этого, вы должны легко найти часы в течение любого периода времени (день, вечер, ночь), как это определено в ваших правилах.

1 Ответов

Рейтинг:
2

Maciej Los

Я бы посоветовал использовать Moment.js[^]. Это позволяет вам "Анализ, проверка, манипулирование и отображение дат и времени в JavaScript".