paint-brush
Добавляйте временные интервалы в JavaScript простым способомк@anwarhjg
740 чтения
740 чтения

Добавляйте временные интервалы в JavaScript простым способом

к AHJ George4m2024/01/13
Read on Terminal Reader

Слишком долго; Читать

У вас есть строка расписания, зависающий босс и JavaScript. Проблема: вы хотите сложить часы и остановить зависание вашего начальника. Решение: Не требует колдовства.
featured image - Добавляйте временные интервалы в JavaScript простым способом
AHJ George HackerNoon profile picture
0-item

Для выполнения этого урока вам не понадобятся никакие колдовские принадлежности. Изображение автора.



Хуууф. Холодная скованность пробегает по позвоночнику.


Хааааа. Холодное дыхание вашего босса омывает вашу шею, как переполненная канализация. Но вы не можете приказать им зависнуть где-то еще... они следят за вами, как ястреб, с тех пор, как в офисе сломалась система учета рабочего времени.


Теперь они просто здесь... парят... дышат. Хафффффф.


Вы пытались записать свои часы в табеле учета рабочего времени, но ваш начальник очень занят всем этим дыханием. Что, если они неправильно посчитали и неправильно прибавили часы?


Вот как можно взять дело в свои руки с помощью JavaScript. Хааааа .

Проблема

У вас есть расписание, которое выглядит как содержимое этой String :

 const a = `November 30 2023 13:20-15:00, 15:30-16:40 December 4 2023 15:45-16:15, December 5 2023 08:00-08:30, 18:15-19:30, 21:45-22:15, 22:30-23:00 December 6 2023 19:45-21:45 December 7 2023 14:15-14:45, 15:15-15:45, 16:00-16:30, 16:45-17:15, 18:45-20:15, 20:45-22:45 December 13 2023 03:00-03:50 December 15 2023 09:00-09:30 20:30-21:15 21:45-22:30 23:30-24:00 December 16 2023 23:25-23:55 December 17 2023 19:05-19:50 20:30-21:30 22:15-23:45 December 20 2023 23:30-24:00 December 21 2023 02:20-2:50 03:15-03:30 13:40-14:00 16:00-17:15 17:45-18:45 19:20-20:10 21:30-22:20 23:00 - 24:00 December 22 2023 0:00-0:15`;


Каждая строка содержит дату, за которой следуют некоторые временные интервалы. Но они написаны не очень четко — некоторые интервалы разделены запятыми, другие неравномерны и т. д.


Учитывая эти несоответствия, вероятно, было бы хорошо предположить отсутствие других гарантий. Например, кто сказал, что все время будет относиться к одному и тому же году? Никто, вот кто. Вы хотите сложить часы как можно точнее.

Решение

Это довольно легко. Начнем с создания пары регулярных выражений и вспомогательной функции. Тогда мы просто… Уууууф!


Фу!! Босс, иди остынь куда-нибудь на секунду!


Как я уже говорил, теперь мы можем выполнить задачу по трехшаговому алгоритму:


  1. Мы разделяем строку расписания на отдельные строки и сокращаем их, чтобы создать массив объектов.


  2. Для каждой итерации мы:

    A. Разделите строку на год с помощью yearRegex , записав строку даты.

    Б. Соберите все интервалы временного диапазона с помощью intervalsRegex .

    C. Уменьшите диапазоны времени, анализируя каждый из них как объект Date JavaScript с помощью помощника parseDate и строки даты из шага 2.A.


  3. Сократите массив объектов, чтобы найти общее количество часов.


 const yearRegex = /(\d{4})/gi; const intervalsRegex = /(\d+\:\d+)\s*-\s*(\d+\:\d+)/gi; const parseDate = (date, time) => Date.parse(`${date} ${time}`); let times = [...a.split("\n")].reduce((arr, entryLine) => { let entryLineSplit = entryLine.split(yearRegex); let o = { date: entryLineSplit[0] + entryLineSplit[1], timeRanges: [...entryLine.matchAll(intervalsRegex)], }; o.hoursForDay = o.timeRanges.reduce((total, [x, start, end]) => { let s = parseDate(o.date, start); let e = parseDate(o.date, end); return total + (e - s) / 1000 / 60 / 60; }, 0); return [...arr, o]; }, []); console.log(times); let totalHours = times.reduce((total, { hoursForDay }) => total + hoursForDay, 0); console.log(totalHours);


Если вы раскомментируете console.log(times); вы увидите массив, содержащий такие объекты, как:

 { date: 'November 30 2023', timeRanges: [ [ '13:20-15:00', '13:20', '15:00', index: 17, input: 'November 30 2023 13:20-15:00, 15:30-16:40', groups: undefined ], [ '15:30-16:40', '15:30', '16:40', index: 30, input: 'November 30 2023 13:20-15:00, 15:30-16:40', groups: undefined ] ], totalHours: 2.8333333333333335 },

Преимущества этого метода

Создание массива объектов имеет несколько явных преимуществ по сравнению с простым извлечением временных интервалов и их добавлением.


  • Это облегчает обход постфактум. Это идеально, если вы хотите построить график своего ежедневного времени.


  • Сохранение строки даты для каждой записи позволяет использовать встроенные методы арифметики даты JS после вызова Date.parse .


  • Объект — удобное место для хранения результатов вызова String.prototype.split , которые могут быть не уникальными в зависимости от того, включали ли два дня одинаковые временные интервалы.

Недостатки этого метода

Это решение не идеально:

  • Это требует двух больших обходов — один раз по результату разделения расписания, а затем по объекту times . Чтобы оптимизировать этот код, вероятно, было бы лучше использовать одно сокращение для пустого объекта, содержащего totalHours и times в качестве полей.


  • Он использует регулярные выражения, которые могут усложниться в более сложном формате.

Подведение итогов

Теперь вы знаете, как извлечь время из беспорядочного расписания. Приложив немного дополнительных усилий, вы могли бы даже построить полноценные часы. Но тогда вам не удастся потратить столько приятного времени на знакомство со своим боссом, не так ли? Хафффф.