【问题标题】:react date range calculate (opened business hours)反应日期范围计算(营业时间)
【发布时间】:2021-04-21 14:20:03
【问题描述】:

我想计算我的企业在一周内营业的时间。 我一周有很多时间段。 问题是其中一些重叠,计算错误。 这是一个例子:

在我的日子里,我有 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 小时。

感谢您的帮助

【问题讨论】:

    标签: reactjs date range momentjs overlap


    【解决方案1】:

    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))
    );
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment-with-locales.min.js"&gt;&lt;/script&gt;

    [原答案]

    假设数组中每个对象中的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并将其用于此类任务

    【讨论】:

    • 感谢您的回复,但对象可以包含一周中不同日期的范围:从星期一到星期日
    • 我假设同一天只在对象中而不是在所有数组中。最后 daysHours 在数组中的每一天都有一个键
    • 是的,但有时,它不起作用:ibb.co/TK8Tqvh
    • 如果我在一天内使用多个范围,这是行不通的:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多