计算日期间隔内的日期

发布于 2025-01-13 18:40:16 字数 963 浏览 4 评论 0原文

我有一个包含日期和时间的数组 abc 。我需要将其转换为 1 天的时间段,其限制由 startDateendDate 确定,其中“x”包含时间段,“y”包含这些时间段内的发生次数插槽。如何根据间隔获取 abc 中出现的次数,并根据日期间隔正确映射它?

const abc = ['2021-09-05T00:53:44.953Z', '2021-08-05T05:08:10.950Z', '2022-03-05T00:53:40.951Z'];
const startDate = '2021-07-05'; 
const endDate = '2021-11-05';
const res = [{x: '2021-07-05 - 2021-08-05' , y: '1' },{x: '2021-08-05 - 2021-09-05' , y: '2' }, {x: '2021-09-05 - 2021-10-05' , y: '1' },{x: '2021-10-05 - 2021-11-05' , y: '0' }];
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

I've an array abc containing date and time. I need to convert it into time slots of 1 day with limits determined by startDate and endDate with 'x' containing time slots and 'y' containing count of occurrence in those time slots. How can I get the count of occurrences in abc as per the interval and map it correctly it as per the date intervals?

const abc = ['2021-09-05T00:53:44.953Z', '2021-08-05T05:08:10.950Z', '2022-03-05T00:53:40.951Z'];
const startDate = '2021-07-05'; 
const endDate = '2021-11-05';
const res = [{x: '2021-07-05 - 2021-08-05' , y: '1' },{x: '2021-08-05 - 2021-09-05' , y: '2' }, {x: '2021-09-05 - 2021-10-05' , y: '1' },{x: '2021-10-05 - 2021-11-05' , y: '0' }];
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

煮酒 2025-01-20 18:40:16

根据我的理解,我根据您在问题中提供的开始结束日期创建了一个简单的工作演示

const abc = ['2021-09-05T00:53:44.953Z', '2021-08-05T05:08:10.950Z', '2022-03-05T00:53:40.951Z'];

const startDate = '2021-07-05'; 
const endDate = '2021-11-05';

function countDates(inputArray, startDate, endDate) {
    let count = 0;
  const dateArray = abc.map((item) => new Date(item.split("T")[0]).getTime());

  dateArray.forEach((dayTime) => {
    if(dayTime >= new Date(startDate).getTime() && dayTime <= new Date(endDate).getTime()) {
      count ++;
    }
  });
  
  return [{x: `${startDate} - ${endDate}`, y: count}];
}

console.log(countDates(abc, startDate, endDate));

注意:我假设您必须在 startDateendDate 之间一次获取一个范围。

As per my understanding, I created a simple working demo as per the start and end date you provided in the question :

const abc = ['2021-09-05T00:53:44.953Z', '2021-08-05T05:08:10.950Z', '2022-03-05T00:53:40.951Z'];

const startDate = '2021-07-05'; 
const endDate = '2021-11-05';

function countDates(inputArray, startDate, endDate) {
    let count = 0;
  const dateArray = abc.map((item) => new Date(item.split("T")[0]).getTime());

  dateArray.forEach((dayTime) => {
    if(dayTime >= new Date(startDate).getTime() && dayTime <= new Date(endDate).getTime()) {
      count ++;
    }
  });
  
  return [{x: `${startDate} - ${endDate}`, y: count}];
}

console.log(countDates(abc, startDate, endDate));

Note : I am assuming you have to fetch a range once at a time between startDate and endDate.

烟酉 2025-01-20 18:40:16

这可能是实现预期目标的一种可能的解决方案:

代码片段

请查看countWithinLimits方法,它包含解决方案的重要部分。

const data = [
  '2021-07-05T00:53:44.953Z', '2021-07-04T00:53:44.953Z', 
  '2021-07-14T00:53:44.953Z', '2021-07-12T00:53:44.953Z', 
  '2021-07-06T00:53:44.953Z', '2021-07-05T00:53:44.953Z', 
  '2021-07-07T00:53:44.953Z', '2021-07-11T00:53:44.953Z', 
  '2021-07-08T00:53:44.953Z', '2021-07-10T00:53:44.953Z', 
  '2021-07-09T00:53:44.953Z', '2021-07-07T00:53:44.953Z', 
  '2021-07-10T00:53:44.953Z', '2021-07-05T00:53:44.953Z', 
  '2021-07-11T00:53:44.953Z', '2021-07-07T00:53:44.953Z', 
];
const startDate = '2021-07-05';
const endDate = '2021-07-11';

// expected result structure for reference
const expectedResult = [
  {x: '2021-07-05 - 2021-07-06', y: '1' },
  {x: '2021-07-06 - 2021-07-07', y: '2' },
  {x: '2021-07-07 - 2021-07-08', y: '1' },
  {x: '2021-07-08 - 2021-07-09', y: '0' }
];

const countWithinLimits = (st, en, arr = data) => {

  // helper function to add 'i' days to given 'dt'
  const addDays = (dt, i) => {
    const nx = new Date(dt);
    return (
        (
        new Date(nx.setDate(nx.getDate() + i))
        ).toISOString().split('T')[0]
    );
  };
  
  // transform 'dt' into look like 'x' in the expected result
  const transformToKey = dt => (`${dt} - ${addDays(dt, 1)}`);
  
  // set constants for start and end dates
  const stDate = new Date(st), enDate = new Date(en);
  
  // first determine the number of slots
  // (each will be 1-day duration, from st till en)
  const numDays = (
    Math.ceil(
      Math.abs(enDate - stDate) / (1000 * 60 * 60 * 24)
    )
  );
  
  // next, obtain an array with the slots
  // something like this: ['2021-07-05 - 2021-07-06', ....]
  const slots = (
    [...Array(numDays).keys()]
    .map(i => addDays(st, i))
    .map(d => transformToKey(d))
  );
  
  // generate an object with props as the slots and values as zeroes
  // like this: { '2021-07-05 - 2021-07-06': 0, ....}
  const slotObj = slots.reduce(
    (fin, itm) => ({...fin, [itm]: 0}),
    {}
  );
  
  // iterate through the data (arr)
  // find the slot in which a given date fits
  // and add 1 to the counter, if the slot is found in slotObj
  // do not count the date if it doesn't match any slots
  const countPerSlot = arr.reduce(
    (fin, itm) => ({
        ...fin,
      ...(
        [transformToKey(itm.split('T')[0])] in fin
        ? {
            [transformToKey(itm.split('T')[0])]: (
            fin[transformToKey(itm.split('T')[0])] + 1
          )
        }
        : {}
      )
    }),
    {...slotObj}
  );
  
  // finally, transform the countPerSlot object 
  // into the expected result array
  return (
    Object.entries(countPerSlot)
    .map(
      ([k, v]) => ({ x: k, y: v})
    )
  );
};

console.log(countWithinLimits(startDate, endDate));

解释

虽然上面的代码片段中有内嵌注释,但如果有任何具体点需要更详细的解释,下面的“注释”可能会被用来通知,并且这个答案可能会被更新有更多细节。

总体思路是这样的:

  • 首先将解决方案分成不同的较小部分
  • ,然后生成时间段(长度为 1 天)
  • ,创建一个对象,其中 props 是周期(例如 2021-07-05 - 2021-07-06)
  • 现在,迭代数据并递增与日期适合的 prop 相对应的计数器
  • ,最后将对象转换为与预期结果匹配的数组 ([ {x : '2021-07-05 - 2021-07-06', y: '2' }, .... ])

This may be one possible solution to achieve the desired objective:

Code Snippet

Please look at countWithinLimits method which houses the significant portions of the solution.

const data = [
  '2021-07-05T00:53:44.953Z', '2021-07-04T00:53:44.953Z', 
  '2021-07-14T00:53:44.953Z', '2021-07-12T00:53:44.953Z', 
  '2021-07-06T00:53:44.953Z', '2021-07-05T00:53:44.953Z', 
  '2021-07-07T00:53:44.953Z', '2021-07-11T00:53:44.953Z', 
  '2021-07-08T00:53:44.953Z', '2021-07-10T00:53:44.953Z', 
  '2021-07-09T00:53:44.953Z', '2021-07-07T00:53:44.953Z', 
  '2021-07-10T00:53:44.953Z', '2021-07-05T00:53:44.953Z', 
  '2021-07-11T00:53:44.953Z', '2021-07-07T00:53:44.953Z', 
];
const startDate = '2021-07-05';
const endDate = '2021-07-11';

// expected result structure for reference
const expectedResult = [
  {x: '2021-07-05 - 2021-07-06', y: '1' },
  {x: '2021-07-06 - 2021-07-07', y: '2' },
  {x: '2021-07-07 - 2021-07-08', y: '1' },
  {x: '2021-07-08 - 2021-07-09', y: '0' }
];

const countWithinLimits = (st, en, arr = data) => {

  // helper function to add 'i' days to given 'dt'
  const addDays = (dt, i) => {
    const nx = new Date(dt);
    return (
        (
        new Date(nx.setDate(nx.getDate() + i))
        ).toISOString().split('T')[0]
    );
  };
  
  // transform 'dt' into look like 'x' in the expected result
  const transformToKey = dt => (`${dt} - ${addDays(dt, 1)}`);
  
  // set constants for start and end dates
  const stDate = new Date(st), enDate = new Date(en);
  
  // first determine the number of slots
  // (each will be 1-day duration, from st till en)
  const numDays = (
    Math.ceil(
      Math.abs(enDate - stDate) / (1000 * 60 * 60 * 24)
    )
  );
  
  // next, obtain an array with the slots
  // something like this: ['2021-07-05 - 2021-07-06', ....]
  const slots = (
    [...Array(numDays).keys()]
    .map(i => addDays(st, i))
    .map(d => transformToKey(d))
  );
  
  // generate an object with props as the slots and values as zeroes
  // like this: { '2021-07-05 - 2021-07-06': 0, ....}
  const slotObj = slots.reduce(
    (fin, itm) => ({...fin, [itm]: 0}),
    {}
  );
  
  // iterate through the data (arr)
  // find the slot in which a given date fits
  // and add 1 to the counter, if the slot is found in slotObj
  // do not count the date if it doesn't match any slots
  const countPerSlot = arr.reduce(
    (fin, itm) => ({
        ...fin,
      ...(
        [transformToKey(itm.split('T')[0])] in fin
        ? {
            [transformToKey(itm.split('T')[0])]: (
            fin[transformToKey(itm.split('T')[0])] + 1
          )
        }
        : {}
      )
    }),
    {...slotObj}
  );
  
  // finally, transform the countPerSlot object 
  // into the expected result array
  return (
    Object.entries(countPerSlot)
    .map(
      ([k, v]) => ({ x: k, y: v})
    )
  );
};

console.log(countWithinLimits(startDate, endDate));

Explanation

While there are comments in-line in the above code-snippet, should there be any specific point that requires a more detailed explanation, 'comments' below may be used to notify and this answer may be updated with more details.

The big-picture idea is this:

  • split the solution into different smaller-parts
  • first, generate the time-slots (of length 1 day)
  • next, create an object where the props is the period (like 2021-07-05 - 2021-07-06)
  • now, iterate through the data and increment a counter corresponding to the prop where the date fits
  • and finally, transform the object into an array that matches the expected result ([ {x : '2021-07-05 - 2021-07-06', y: '2' }, .... ])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文