Как разделить временные интервалы на дневные, используя javascript? - PullRequest
0 голосов
/ 31 декабря 2018

Любая помощь будет по достоинству оценена!Я пытаюсь с 4 дней, но до сих пор не нашел никакого решения.Пожалуйста, помогите мне.Проведите меня за библиотекой или методами, которые я могу использовать.

Здесь приведены данные ввода.массив начала и конца сеанса.Я хочу рассчитать ежедневный период использования.Поэтому я хочу разделить каждый слот в свой день.

var slots = [
  { start: dayjs('2019-01-01 21:00:00'), end: dayjs('2019-01-01 23:00:00') },
  { start: dayjs('2019-01-01 22:00:00'), end: dayjs('2019-01-02 01:00:00') },
  { start: dayjs('2019-01-01 22:00:00'), end: dayjs('2019-01-02 04:00:00') },
  { start: dayjs('2019-01-01 21:00:00'), end: dayjs('2019-01-02 00:00:00') },
  { start: dayjs('2019-01-02 00:00:00'), end: dayjs('2019-01-02 04:00:00') },
  { start: dayjs('2019-01-02 01:00:00'), end: dayjs('2019-01-02 04:00:00') },
  { start: dayjs('2019-01-31 01:00:00'), end: dayjs('2019-02-01 04:00:00') },
]
var output = []

slots.forEach((slot) => {
  // filter same slots with same day
  if (slot.start.isSame(slot.end, 'day')) {
    output.push(slot)
  } else {
  // what to do here? how to split end time
  }
})
console.log(output)

Мне нужен такой вывод

[
  { start: '2019-01-01 21:00:00', end: '2019-01-01 23:00:00' },
  { start: '2019-01-01 22:00:00', end: '2019-01-01 23:59:59' },
  { start: '2019-01-02 00:00:00', end: '2019-01-02 01:00:00' },
  { start: '2019-01-01 22:00:00', end: '2019-01-01 23:59:59' },
  { start: '2019-01-02 00:00:00', end: '2019-01-02 04:00:00' },
  { start: '2019-01-01 21:00:00', end: '2019-01-01 23:59:59' },
  { start: '2019-01-02 00:00:00', end: '2019-01-02 00:00:00' },
  { start: '2019-01-02 00:00:00', end: '2019-01-02 04:00:00' },
  { start: '2019-01-02 01:00:00', end: '2019-01-02 04:00:00' },
  { start: '2019-01-31 01:00:00', end: '2019-01-31 23:59:59' },
  { start: '2019-02-01 00:00:00', end: '2019-02-01 04:00:00' },
]

Ответы [ 3 ]

0 голосов
/ 31 декабря 2018

Идея будет состоять в том, чтобы итеративно разделить временной интервал на два: первый - от начала временного интервала до конца дня начального времени, а второй - от начала следующего днявремя начала (добавление дня) к времени окончания.

{ start: dayjs('2019-01-01T22:00:00-00:00'), end: dayjs('2019-01-02T01:00:00-00:00') }

становится

[
  { start: dayjs('2019-01-01T22:00:00-00:00'), end: dayjs('2019-01-02T23:59:59-00:00') },
  { start: dayjs('2019-01-02T00:00:00-00:00'), end: dayjs('2019-01-02T01:00:00-00:00') }
]

Обратите внимание, что dayjs по умолчанию использует полный формат DateTime.

Алгоритм [Обновлено с новой информацией о многодневных слотах от @asissuthar]

const slotHopper = { ...slot }; // don't mutate original slot
while (!slotHopper.start.isSame(slotHopper.end, "day")) {
  // peel off first day of slot
  const splitSlot = {
    start: slotHopper.start,
    end: dayjs(slotHopper.start).endOf("day")
  };
  acc.push(splitSlot);
  // update start to beginning of next day
  slotHopper.start = dayjs(slotHopper.start)
    .add(1, "day")
    .startOf("day");
}
acc.push(slotHopper);

Я извлек вышеперечисленное в функцию редуктора в следующем примере песочницы: https://codesandbox.io/s/lp0z5x7zw9, где accмассив накопления для результата.

0 голосов
/ 31 декабря 2018

Наконец-то найдено решение.это работает идеально. Выполнить

import dayjs from "dayjs";

const slots = [
  { start: dayjs("2019-01-01 21:00:00"), end: dayjs("2019-01-01 23:00:00") },
  { start: dayjs("2019-01-01 22:00:00"), end: dayjs("2019-01-02 01:00:00") },
  { start: dayjs("2019-01-01 22:00:00"), end: dayjs("2019-01-02 04:00:00") },
  { start: dayjs("2019-01-01 21:00:00"), end: dayjs("2019-01-02 00:00:00") },
  { start: dayjs("2019-01-02 00:00:00"), end: dayjs("2019-01-02 04:00:00") },
  { start: dayjs("2019-01-02 01:00:00"), end: dayjs("2019-01-02 04:00:00") },
  { start: dayjs("2019-01-31 01:00:00"), end: dayjs("2019-02-01 04:00:00") },
  { start: dayjs("2019-02-01 01:00:00"), end: dayjs("2019-02-04 04:00:00") }
];

function splitDayWise(slots) {
  let output = [];

  function pushSlot(slot, start, end) {
    output.push({
      ...slot
    });

    let top = output[output.length - 1];
    top.start = start;
    top.end = end;
    top.time = top.end - top.start;
  }

  slots.forEach(slot => {
    if (slot.start.isSame(slot.end, "day")) {
      pushSlot(slot, slot.start, slot.end);
    } else {
      while (!slot.start.isSame(slot.end, "day")) {
        pushSlot(slot, slot.start, slot.start.endOf("day"));
        slot.start = slot.start.add(1, "day").startOf("day");
      }
      pushSlot(slot, slot.start, slot.end);
    }
  });

  return output;
}

const daywiseSlots = splitDayWise(slots).map(slot => ({
  start: slot.start.format("YYYY-MM-DD HH:mm:ss"),
  end: slot.end.format("YYYY-MM-DD HH:mm:ss"),
  time: slot.time
}));

console.log(JSON.stringify(daywiseSlots, null, 2));
0 голосов
/ 31 декабря 2018

Вы можете сделать следующее, используя reduce.Я не знаю dayjs.Я предполагаю, что вы используете его только для сравнения части даты, а она не является частью исходного массива.Итак, вместо этого я создал функцию, которая дает только часть date для start и end.

const slots = [
  { start: '2019-01-01 21:00:00', end: '2019-01-01 23:00:00' },
  { start: '2019-01-01 22:00:00', end: '2019-01-02 01:00:00' },
  { start: '2019-01-01 22:00:00', end: '2019-01-02 04:00:00' },
  { start: '2019-01-01 21:00:00', end: '2019-01-02 00:00:00' },
  { start: '2019-01-02 00:00:00', end: '2019-01-02 04:00:00' },
  { start: '2019-01-02 01:00:00', end: '2019-01-02 04:00:00' },
  { start: '2019-01-31 01:00:00', end: '2019-02-01 04:00:00' }];
  
const getDay = (date) => date.split(" ")[0];

const newArray = slots.reduce((acc, {start,end}) => {
    if (getDay(start) != getDay(end))
        acc.push({ start, end: `${getDay(start)} 23:59:59` }, 
                 { start: `${getDay(end)} 00:00:00`, end });
    else
        acc.push({ start, end })
    return acc
}, []);

console.log(newArray)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...