Хуууф. Холодная скованность пробегает по позвоночнику.
Хааааа. Холодное дыхание вашего босса омывает вашу шею, как переполненная канализация. Но вы не можете приказать им зависнуть где-то еще... они следят за вами, как ястреб, с тех пор, как в офисе сломалась система учета рабочего времени.
Теперь они просто здесь... парят... дышат. Хафффффф.
Вы пытались записать свои часы в табеле учета рабочего времени, но ваш начальник очень занят всем этим дыханием. Что, если они неправильно посчитали и неправильно прибавили часы?
Вот как можно взять дело в свои руки с помощью 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`;
Каждая строка содержит дату, за которой следуют некоторые временные интервалы. Но они написаны не очень четко — некоторые интервалы разделены запятыми, другие неравномерны и т. д.
Учитывая эти несоответствия, вероятно, было бы хорошо предположить отсутствие других гарантий. Например, кто сказал, что все время будет относиться к одному и тому же году? Никто, вот кто. Вы хотите сложить часы как можно точнее.
Это довольно легко. Начнем с создания пары регулярных выражений и вспомогательной функции. Тогда мы просто… Уууууф!
Фу!! Босс, иди остынь куда-нибудь на секунду!
Как я уже говорил, теперь мы можем выполнить задачу по трехшаговому алгоритму:
Мы разделяем строку расписания на отдельные строки и сокращаем их, чтобы создать массив объектов.
Для каждой итерации мы:
A. Разделите строку на год с помощью yearRegex
, записав строку даты.
Б. Соберите все интервалы временного диапазона с помощью intervalsRegex
.
C. Уменьшите диапазоны времени, анализируя каждый из них как объект Date JavaScript с помощью помощника parseDate
и строки даты из шага 2.A.
Сократите массив объектов, чтобы найти общее количество часов.
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 },
Создание массива объектов имеет несколько явных преимуществ по сравнению с простым извлечением временных интервалов и их добавлением.
Date.parse
.
String.prototype.split
, которые могут быть не уникальными в зависимости от того, включали ли два дня одинаковые временные интервалы.Это решение не идеально:
times
. Чтобы оптимизировать этот код, вероятно, было бы лучше использовать одно сокращение для пустого объекта, содержащего totalHours
и times
в качестве полей.
Теперь вы знаете, как извлечь время из беспорядочного расписания. Приложив немного дополнительных усилий, вы могли бы даже построить полноценные часы. Но тогда вам не удастся потратить столько приятного времени на знакомство со своим боссом, не так ли? Хафффф.