反应日期范围计算(营业时间)

react date range calculate (opened business hours)

我想计算一周内我的公司营业时间。 我有一周的一系列时间段。 问题是有些重叠了,计算有误。 这是一个例子:

在我的一天,我有 3 个这样的范围:

数组是这样的:

const obj = [
  {
    startDate: 'Mon Apr 19 2021 08:30:00 GMT+0200',
    endDate: 'Mon Apr 19 2021 12:00:00 GMT+0200'
  },
  {
    startDate: 'Mon Apr 19 2021 09:00:00 GMT+0200',
    endDate: 'Mon Apr 19 2021 12:30:00 GMT+0200'
  },
  {
    startDate: 'Mon Apr 19 2021 09:30:00 GMT+0200',
    endDate: 'Mon Apr 19 2021 13:00:00 GMT+0200'
  },
  ...
]

(这是一个小例子,因为我这周还有其他路口)

最后,我所做的,但交叉点的错误是:

const total = (obj.length > 0)
? obj.map(item => {
    const end = moment(item.endDate)
    const start = moment(item.startDate)
    const duration = moment.duration(end.diff(start))
    return duration.asHours()
  }).reduce((a, b) => a + b)
: 0

这里的结果是 10.5 小时:这是错误的 我不知道如何考虑重叠范围以获得真正的结果:从 8:30 到 13:00 工作所以好的结果是 4.5 小时。

感谢帮助

let entries = [
  {
    startDate: "2021-04-19 09:30:00",
    endDate: "2021-04-19 13:00:00"
  },
  {
    startDate: "2021-04-19 08:30:00",
    endDate: "2021-04-19 12:00:00"
  },
  {
    startDate: "2021-04-19 09:00:00",
    endDate: "2021-04-19 12:30:00"
  },
  {
    startDate: "2021-04-19 15:00:00",
    endDate: "2021-04-19 17:30:00"
  }
];

entries = entries
  .map((obj) => ({
    startDate: moment(obj.startDate).valueOf(),
    endDate: moment(obj.endDate).valueOf()
  }))
  .sort((obj1, obj2) => obj1.startDate - obj2.startDate);
const ranges = [entries[0]];

for (let obj of entries) {
  let lastRange = ranges[ranges.length - 1];
  if (obj.startDate <= lastRange.endDate) {
    ranges[ranges.length - 1].startDate = Math.min(
      lastRange.startDate,
      obj.startDate
    );
    ranges[ranges.length - 1].endDate = Math.max(
      lastRange.endDate,
      obj.endDate
    );
  } else {
    ranges.push(obj);
  }
}

console.log(
  ranges.map((range) => (range.endDate - range.startDate) / (1000 * 60 * 60))
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment-with-locales.min.js"></script>

[原回答]

假设数组中每个对象中的 startDateendDate 都是同一天,可能的方法如下

const daysHours = {};

obj.forEach((item) => {
  const day = moment(item.endDate).format("YYYY-MM-DD");
  daysHours[day] = daysHours[day] || { min: 60 * 24, max: 0 };
  daysHours[day].min = Math.min(
    moment(item.startDate).hours() * 60 + moment(item.startDate).minutes(),
    daysHours[day].min
  );
  daysHours[day].max = Math.max(
    moment(item.endDate).hours() * 60 + moment(item.endDate).minutes(),
    daysHours[day].max
  );
  daysHours[day].minutes = daysHours[day].max - daysHours[day].min;
});

console.log(daysHours);

在你的例子中console.log(daysHours)的输出是

{
  2021-04-19: {
    min: 510
    max: 780
    minutes: 270
  }
}

270 分钟 = 4.5 小时

如果可以,我建议您导入 moment-range 并将其用于此类任务