【问题标题】:How to find what period of given timespans is currently如何找到当前给定时间跨度的时间段
【发布时间】:2021-07-26 18:59:43
【问题描述】:

我得到了 6 个小时和分钟的时间戳,它们定义了一段时间,我们称它们为 1 到 6。 (例如:03:13、05:22、12:54、16:55、20:23、22:14)

例如:第一节从 03:13 开始,一直持续到 05:22 -1 分钟,以此类推

当然,最后,月经必须涵盖一天中的所有 24 小时,因此第六个月经(从 22:14 开始)将持续到 03:13

编写一个可以告诉我们当前处于什么时间段的函数的最佳/最佳方法是什么?

这是我的尝试(不起作用并且不是最理想的):

    function currentPeriod(hrs, mins, now) {
       // hrs is an array of integers and they define only hours (3, 5, 12,...)
       // mins is an array of integers and they define minutes (13, 22, 54,...)
       // now is a JavaScript Date

       if(now.getHours() > 0 && now.getHours() < hrs[0]) { return 6; }
       else if(now.getHours() == hrs[0] && now.getMinutes() < mins[0]) { return 6; }
       else if(now.getHours() == hrs[0] && now.getMinutes() >= mins[0]) { return 1; }
    
       else if(now.getHours() > hrs[0] && now.getHours() < hrs[1]) { return 1; }
       else if(now.getHours() == hrs[1] && now.getMinutes() < mins[1]) { return 1; }
       else if(now.getHours() == hrs[1] && now.getMinutes() >= mins[1]) { return 2; }
    
       else if(now.getHours() > hrs[1] && now.getHours() < hrs[2]) { return 2; }
       else if(now.getHours() == hrs[2] && now.getMinutes() < mins[2]) { return 2; }
       else if(now.getHours() == hrs[2] && now.getMinutes() >= mins[2]) { return 3; }
    
       else if(now.getHours() > hrs[2] && now.getHours() < hrs[3]) { return 3; }
       else if(now.getHours() == hrs[3] && now.getMinutes() < mins[3]) { return 3; }
       else if(now.getHours() == hrs[3] && now.getMinutes() >= mins[3]) { return 4; }
    
       else if(now.getHours() > hrs[3] && now.getHours() < hrs[4]) { return 4; }
       else if(now.getHours() == hrs[4] && now.getMinutes() < mins[4]) { return 4; }
       else if(now.getHours() == hrs[4] && now.getMinutes() >= mins[4]) { return 5; }
    
       else if(now.getHours() > hrs[4] && now.getHours() < hrs[5]) { return 5; }
       else if(now.getHours() == hrs[5] && now.getMinutes() < mins[5]) { return 5; }
       else if(now.getHours() == hrs[5] && now.getMinutes() >= mins[5]) { return 6; }
       else if(now.getHours() <= 23 && now.getMinutes() <= 59) { return 6; }
    }

【问题讨论】:

  • 嗨 BakirGracic,以下答案之一是否解决了您的问题?如果是这样,请使用绿色复选标记接受其中之一。它让回答者知道您的问题已经解决。如果没有,请详细说明您仍然遇到的问题。

标签: javascript jquery date


【解决方案1】:

一般来说,在处理数组时最好使用循环而不是 ifs 块或 switch/case 的东西。好处很多,但特别是在循环中运行逻辑可以让您

  • 写一次。
  • 有任意数量的案例。

我不确定您项目中的 hrsmins 是否被指定为不相关的数组,或者这是您在此步骤之前采取的步骤。最好将小时和分钟放在一起。特别是,如果hrsmins 没有的额外条目结束,则很容易破坏您的代码。我写了这个例子,假设将间隔作为字符串数组传递给“23:43”是相当容易的。代码中的注释有一个建议的方法来构建这个字符串,如果你没有的话。

function currentPeriod(intervals, now) {
  // Break these out so the methods are only called once.
  const nowHour = now.getHours();
  const nowMinute = now.getMinutes();
  
  // Iterate over all the intervals. If having the intervals broken into separate
  // arrays is a requirement of the project, they should be recombined like this:
  // ```
  // const intervals = hrs.map((h, i) => `${h}:${mins[i]}`);
  // ```
  for (let i = 0; i < intervals.length; i++) {
    // Get the hour and minute of the end of the interval.
    const [hour, minute] = intervals[i].split(":").map(a => +a);
    if (hour > nowHour) {
      // If the hour is after the current time, this is the correct interval. 
      return i;
    }
    else if (hour === nowHour && minute > nowMinute) {
      // If the hour is the same as the current time, and the minute is after
      // the current time, this is the correct interval.
      return i;
    }
  }
  // If the current time is after the last interval, say it's in the first
  // interval.
  return 0;
}

const intervals = ["03:13", "05:22", "12:54", "16:55", "20:23", "22:14"];

console.log("00:00", currentPeriod(intervals, new Date("2020-01-01T00:00:00")));
console.log("03:13", currentPeriod(intervals, new Date("2020-01-01T03:13:00")));
console.log("12:59", currentPeriod(intervals, new Date("2020-01-01T12:59:00")));
console.log("22:15", currentPeriod(intervals, new Date("2020-01-01T22:15:00")));

注意:只需要查看当前时间是否在下一个时间间隔之前,因为如果它在前一个时间间隔之前,循环将在那个时间间隔上退出。这样可以节省一半的解决方案复杂性,因为事情不会被检查两次。

【讨论】:

  • 就是这样!完美运行。我只是想不出如何做到这一点,只是在这里问。谢谢!
【解决方案2】:

由于只需要考虑一天中的时间,我们可以在不使用完整 Date 对象的情况下进行计算。我将基于字符串的区间转换为数字并将它们存储在intv 中。通过将小时部分乘以 100 并加上分钟(变量 n),可以将要测试的时间值 (dt) 转换为整数。其余的在while 循环中完成,我遍历间隔直到我到达一个大于nintv[p] 值(或者直到我到达数组的末尾:p&lt;int.length 然后将是@ 987654328@)。模运算 (%) 是必要的,因为对于大于最后一个 intv 值的 n 的值,我希望周期数 p 再次为 0(而不是本示例中的 6) .

function period(date){
 const intv = ["03:13", "05:22", "12:54", "16:55", "20:23", "22:14"].map(t=>+t.replace(":",""));
 let p=0,n=100*date.getHours()+date.getMinutes();
 while(n>=intv[p] && p<intv.length) p++
 return p%intv.length;
}

// testing:
let txt,dt=new Date();
for (i=0;i<48;i++){
 txt=dt.toLocaleString("de-DE").substr(-8)+"h: period ";
 console.log(txt+period(dt));
 dt.setMinutes(dt.getMinutes()+30);
}

【讨论】:

  • 应该有算法说明。
  • 这个答案比我的更聪明、更高效。虽然所有的人都出去了,但它是不透明的。
【解决方案3】:

我想提供一个使用 DateTime 对象并具有可读代码的答案。

let periods = ["03:13", "05:22", "12:54", "16:55", "20:23", "22:14"];

let periodDateTimeObjects = [];
periods.forEach(period => {
  let hours = Number(period.slice(0,2));
  let minutes = Number(period.slice(-2));
  periodDateTimeObjects.push(new Date().setUTCHours(hours, minutes, 0, 0));
});

let currentDateTime = new Date();
let periodStart = 0;
periodDateTimeObjects.forEach((periodDateTime, index) => {
  if (currentDateTime > periodDateTime) { periodStart = index; } 
});

let periodEnd = periodStart + 1;
if (periodEnd == periods.length) { periodEnd = 0; }
console.log("Time is now: " + currentDateTime.getHours() + ":" + currentDateTime.getMinutes() + " and current period is " + Number(periodStart + 1) + ": " + periods[periodStart] + " - " + periods[periodEnd]);

【讨论】:

  • 结果应该是周期的单个数字。
  • OP 是否希望它最终格式化取决于他。这里的重点是方法。谢谢你的意见。
猜你喜欢
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-27
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
相关资源
最近更新 更多