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

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

14 января 2024 г.

You will not need any of these witching supplies to complete this tutorial. Image by the author.

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

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

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

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

Вот как можно взять дело в свои руки с помощью 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. 2. Для каждой итерации мы:

    А. Разделите строку на год, используя yearRegex, записывая строку даты

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

    С. Сократите диапазоны времени, анализируя каждый из них как объект 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.

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

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

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


    Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE