如何使用javascript将时间段拆分为每日时间段?

时间:2018-12-31 07:13:44

标签: javascript arrays algorithm datetime

任何帮助将不胜感激!我从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 :(得分:2)

该想法是将一个时隙迭代地分为两个,第一个从时隙的开始到开始时间的一天结束,第二个从时隙的第二天开始开始时间(增加一天)到结束时间。

{ 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是结果的累加数组。

答案 1 :(得分:1)

您可以使用reduce执行以下操作。我不知道dayjs。我假设您仅使用它来比较日期部分,而不是原始数组的一部分。因此,我创建了一个只为datestart提供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)

答案 2 :(得分:0)

最后找到解决方案。它完美地工作。 Execute

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));