一道js题算法:多个时间段如何组成完整的一天24小时

//根据 @CRIMX 的答案进行了修改后的逻辑:

var dateArr1 = [
    {
        ts: '2017-07-22 00:00:00',
        tn: '2017-07-23 09:00:00',
    },
    {
        ts: '2017-07-23 10:00:00',
        tn: '2017-07-23 20:00:00',
    },
    {
        ts: '2017-07-23 20:00:00',
        tn: '2017-07-23 24:00:00',
    }
];

function is24HoursInOneDay(data = [], oneDay) {
        // cs 指定某天的00:00:00
        // cn 指定某天的24:00:00
        let start = 0;
        let end = 0;
            cs = +new Date(`${oneDay} 00:00:00`);
            cn = +new Date(`${oneDay} 24:00:00`);
        let sortData = sortDateArr(data); // 根据时间戳,对时间数组进行排序
        for (let i = 0; i < sortData.length; i++) {
            const ts = sortData[i].ts;// 开始
            const tn = sortData[i].tn;// 结束
            if (ts <= cs) { // 在当天之前
                start = cs;
                if (tn < cn) {
                    // 结束时间小于当天,继续保留计算
                    if (tn > end) { end = tn }
                } else {
                    return true;
                }
            }
            if (ts > cs) {      
                if (ts > end) {
                    // 时间出现间断,当天肯定不满足连续24小时
                    return false;
                } else {
                    if (tn > end) { end = tn }
                }
            }
        }
        return end - start >= 86400000;
}

function sortDateArr(data = []) {
        return data.map((D) => ({
            ts: +new Date(D.ts),
            tn: +new Date(D.tn),
        }))
        .sort((a, b) => a.ts - b.ts);
}

console.log(
is24HoursInOneDay(dateArr1, '2017-07-23')
)

==========================================================
当碰到一个数组,里边有一组时间数组,数组长度不定(内部对象时间段对象固定),如何有效的判断这个数组里的时间段,正好连续满足了24小时,完整的一天呢?
大家有没有好的思路,分享一下。。。

// dateArr1里的时间段满足了7-23是满了24小时的。
var dateArr1 = [
    {
        ts: '2017-07-23 00:00:00',
        tn: '2017-07-23 10:00:00',
    },
    {
        ts: '2017-07-23 10:00:00',
        tn: '2017-07-23 20:00:00',
    },
    {
        ts: '2017-07-23 21:00:00',
        tn: '2017-07-23 24:00:00',
    },
    {
        ts: '2017-07-22 21:00:00',
        tn: '2017-07-23 24:00:00',
    }
];
// dateArr2里的时间段则不满足7-23整天。
var dateArr2 = [
    {
        ts: '2017-07-23 00:00:00',
        tn: '2017-07-23 10:00:00',
    },
    {
        ts: '2017-07-23 10:00:00',
        tn: '2017-07-23 20:00:00',
    },
    {
        ts: '2017-07-23 21:00:00',
        tn: '2017-07-23 24:00:00',
    },
];

数组里面的时间,不会同一天的,有可能跨天,也有可能跨月。
年月时分秒都会出现,
但是ts永远会比tn要小。
大概是每天都会拿到这么个数组,匹配当天的情况,是否在这个数组里,充满了完整的24小时。

阅读 6.2k
2 个回答

讨论了一番重新修改,供参考

function is24 (dateArr) {
  if (!Array.isArray(dateArr) || dateArr.length <= 0) {
    return false
  }

  var start = 0
  var end = 0
  return dateArr
    .map(({ts, tn}) => ({
      ts: new Date(ts + ' GMT+0800').getTime(),
      tn: new Date(tn + ' GMT+0800').getTime()
    }))
    .sort((a, b) => a.ts - b.ts)
    .some(({ts, tn}) => {
      if (ts > end) {
        // 时间出现间断,计算已有时间段
        if (end - start >= 86400000) { return true }
        // 旧的不满足,扔掉重新计算
        start = ts
        end = tn
      } else {
        // ts 在时间段内,根据 tn 适当延长
        if (tn > end) { end = tn }
      }
      return end - start >= 86400000
    })
}

将时间全部转成时间戳,然后放入数组里,再进行排序就行.
循环数组,将时间转成时间戳,然后一组组放入数组对比.如果最后数组中只存在两个值,且第一个是当天的开始时间,最后个是当天的结束时间,则是连续的

var dateArr = [
  {
    ts: '2017-07-23 00:00:00',
    tn: '2017-07-23 10:00:00',
  },
  {
    ts: '2017-07-23 10:00:00',
    tn: '2017-07-23 20:00:00',
  },
  {
    ts: '2017-07-23 21:00:00',
    tn: '2017-07-23 24:00:00',
  },
  {
    ts: '2017-07-23 20:00:00',
    tn: '2017-07-23 24:00:00',
  }
];
function is24(day, dataArray){
  var startTime = new Date(day+' 00:00').getTime();
  var endTime = startTime+24*60*60*1000;
  var ts,tn,array = [];
  if(!Array.isArray(dataArray) || dataArray.length==0){
    return false;
  }else{
    var i, j, k;
    for(i=0;i<dataArray.length;i++){
      ts = new Date(dataArray[i].ts).getTime();
      tn = new Date(dataArray[i].tn).getTime();
      if(ts<startTime){
        ts = startTime;
      }
      if(tn>endTime){
        tn = endTime;
      }
      if(array.length===0){
        array.push(ts, tn);
      }else if(ts<array[0] && tn<array[0]){
        array.unshift(ts, tn);
      }else if(tn>array[array.length-1] && ts>array[array.length-1]){
        array.push(ts, tn);
      }else{
        for(j=0;j<array.length;j++){
          if(ts<=array[j]){
            break;
          }
        }
        for(k=array.length-1;k<=j;k--){
          if(tn>=array[k]){
            break;
          }
        }
        if(tn>=array[k] && ts<=array[j]){
          if(j%2 == 0 && k%2==1){
            array.splice(j, k-j+1, ts, tn)
          }else if(j%2 == 0 && k%2==0){
            array.splice(j, k-j+1, ts)
          }else if(j%2 == 1 && k%2==0){
            array.splice(j, k-j+1)
          }else if(j%2 == 1 && k%2==1){
            array.splice(j, k-j+1, tn);
          }
        }
      }
    }
    if(array[0]==startTime && array[1]==endTime && array.length===2){
      return true;
    }else{
      return false;
    }
  }
}
console.log(is24('2017-07-23', dateArr));

代码有点多,不过功能应该是可以实现的.
没仔细测试,不过我感觉按照我是思路,肯定是可以实现的

推荐问题
宣传栏