【问题标题】:Sort and find closest time from current time排序并查找与当前时间最近的时间
【发布时间】:2018-12-05 12:03:52
【问题描述】:

我有一个时间数组

    ["10:00 PM", "08:00 AM", "12:00 AM", "01:00 AM", "12:00 PM", 
     "03:00 AM", "07:00 AM", "06:00 PM"]

我想对它们进行排序并找到距离当前时间最近的时间,例如,假设现在是下午 05:00,上面的数组应该返回 06:00 PM 作为响应.

我可以用下面的代码对它们进行排序

    let sortedArray = arrayOfData.sort(function (a, b) {
    return parseInt(a.substring(0, 2)) - 
    parseInt(b.substring(0, 2));
    }) 

有人可以建议一种方法对其进行正确排序并找到使用当前时间的最接近时间吗?提前致谢

【问题讨论】:

  • 经络值呢?
  • 它可以是 GMT(+5:30) 甚至是 UTC,我只想用 javascript 函数@NinaScholz 对其进行排序
  • 数字字符串很难排序。相反,您应该将它们解析为更容易排序和计算的东西。也许你可以用Moment.js hh:mm a 解析它们?

标签: javascript arrays json sorting


【解决方案1】:

只需将当前小时和数组小时之间的差异添加到单独的 arraysort 中,然后从 array 获取第一个元素,这将是最合适的小时。

检查以下 sn-p:

times = ["10:00 PM","7:00 PM", "08:00 AM", "12:00 AM", "01:00 AM", "12:00 PM", 
     "03:00 AM", "07:00 AM", "06:00 PM"];

const currentTime = new Date();
const timeDiff = [];

times.sort((a, b) => {
  return a.indexOf('PM');
})

times.filter(time => {
  const _meridianPosition = time.indexOf('AM') > -1 ? 'AM' : 'PM';

  let _time = parseInt(time);

    if(_meridianPosition === 'PM' && _time !== 12) {
      _time += 12;
    } else if(_meridianPosition === 'AM' && _time === 12) {
      _time = 0;
    }

    const k = Math.abs(currentTime.getHours() - _time);
     timeDiff.push({hour: time, diff: k});
});

timeDiff.sort((a,b) => {
  return a.diff - b.diff;
});

console.log(timeDiff[0].hour);

工作小提琴:https://jsbin.com/zojawagiyi/6/edit?js,console

【讨论】:

  • 您的脚本不工作!我的时间是 06:08 PM,当我添加 12:00 AM 和 12:00 PM 元素时,您的函数将 12:00 PM 作为最近的时间而不是 12:00 AM。
【解决方案2】:

我认为这段代码可以完成这项工作。你可以试试这个。

let currentTime = new Date();
let currentHour = parseInt(currentTime.getHours());
let availableDates = ["10:00 PM", "08:00 AM", "12:00 AM", "01:00 AM", "12:00 PM", "03:00 AM", "07:00 AM", "06:00 PM"];
let convertedHours = availableDates.map((date) => {
    let time = parseInt(date.split(' ')[0]);
    let period = date.split(' ')[1];
      
    if(time === 12 && period === 'PM' )
      return time;
      
    if(time < 12 && period === 'AM')
      return time; 
    
    return time + 12;
});

let getNearestTime = (convertedHours, currentHour) => {
    let nearestTime;
    let minValue = convertedHours[0] > currentHour ? (convertedHours[0] - currentHour) : (currentHour - convertedHours[0]);
    convertedHours.reduce((minVal, hour) => {
        let hourDiff = (currentHour > hour) ? currentHour - hour : hour - currentHour;
        if(hourDiff <= minVal) {
            nearestTime = hour;
            return hourDiff;
        } else {
            return minVal;
        }
        
    }, minValue)

    return availableDates[convertedHours.indexOf(nearestTime)];
};
 

console.log(getNearestTime(convertedHours, currentHour));

这里是jsbin链接https://jsbin.com/piwuziqeje/edit?js,console

【讨论】:

    【解决方案3】:

    您可以使用下面的解决方案,对数组进行排序,然后找到距当前时间最近的日期。

    首先,代码将当前时间与数组相加,然后得到最近的日期。

    let dates = ["10:00 PM", "08:00 AM", "12:00 AM", "01:00 AM", "12:00 PM", "03:00 AM", "07:00 AM", "06:00 PM"];
    
    let currentDate = new Date();
    let currentTime = currentDate.getHours() + ':' + currentDate.getMinutes() + (currentDate.getHours() > 12 ? ' PM' : ' AM');
    
    dates.push(currentTime);
    
    dates = dates.sort(function(d1, d2) {
      return compareDates(d1, d2);
    });
    
    console.log(dates);
    
    console.log(nearestDate(dates, currentTime));
    
    function nearestDate(dates, current) {
      let currentIndex = dates.indexOf(current);
      
      if(currentIndex == 0) {
        return dates[currentIndex + 1];
      } else if (currentIndex == dates.length - 1) {
        return dates[currentIndex - 1];
      }
      
      let previousDate = dates[currentIndex - 1]; 
      let nextDate = dates[currentIndex + 1];
    
      let previousDiff = diffDates(previousDate, currentTime);
      let nextDiff = diffDates(nextDate, currentTime);
    
      if(previousDiff < nextDiff) {
        return previousDate;
      } else {
        return nextDate;
      }
    }
    
    function diffDates(d1, d2) {
      let diffHour = Math.abs(getHour(d2) - getHour(d1));
      let diffMin = Math.abs(getMin(d2) - getMin(d1));
      
      return diffHour + diffMin;
    }
    
    function compareDates(d1, d2) {
      let t1 = getHour(d1) + ':' + getMin(d1);
      let t2 = getHour(d2) + ':' + getMin(d2);
      
      if (getHour(d1) == getHour(d2)
          && getMin(d1) < getMin(d2)) {
        return -1;
      } else if(getHour(d1) == getHour(d2)
                && getMin(d1) > getMin(d2)) {
        return 1;
      }
      
      if (getHour(d1) < getHour(d2)) {
        return -1;
      }
      
      if (getHour(d1) > getHour(d2)) {
        return 1;
      }
      
      return 0;
    }
    
    function getHour(d) {
      let hour = parseInt(d.split(' ')[0].split(':')[0], 10);
      if (d.split(' ')[1] === 'PM' && !(hour == 12)) {
        hour += 12;
      }
      return hour;
    }
    
    function getMin(d) {
      return parseInt(d.split(' ')[0].split(':')[1], 10);
    }

    【讨论】:

      【解决方案4】:

      你可以试试这个小代码。

         var timeSrc = ["10:00 PM", "08:00 AM", "11:05 AM", "12:00 AM", "01:00 AM", "12:00 PM", 
           "03:00 AM", "07:00 AM", "06:00 PM"];
          var curDate = new Date();
          curDate = curDate.toDateString();
          var times = timeSrc.map((t) => {
            return new Date(curDate + " " + t); // Make the time as a datetime with current date.
          });
          var now = new Date();
          var min = Math.abs(now - times[0]);
          var result = '';
          //Get the difference of each time with current time. The minimum difference is the closest.
          for(let i = 1; i < times.length; i++) {
            if (Math.abs(now - times[i]) <= min) {
                min = Math.abs(now - times[i]);
                result = timeSrc[i];
             }
          }
          console.log(result);

      你可以试试here

      【讨论】:

      • 您的脚本不工作!我的时间是 06:08 PM,当我添加 12:00 AM 和 12:00 PM 元素时,您的函数将 12:00 PM 作为最近的时间而不是 12:00 AM。
      • 这其实是对的。时间值假设为同一日期。所以对于06:08 PM12:00 PM 最接近同一日期的12:00 AM。但是,如果您认为12:00 AM 是下一个日期,那么12:00 AM 是最接近的。我希望你能理解这个场景。
      【解决方案5】:

      我尝试了一种与我在这里看到的不同/更直观的方法。它可能比某些时间长一点,但在我看来它在做什么更清楚。该代码可以在小提琴中检查。代码如下:

      var times = ["10:00 PM", "08:00 AM", "12:00 AM", "01:00 AM", "12:00 PM", 
       "03:00 AM", "07:00 AM", "06:00 PM"];
      
      //Sort the array
      times.sort(function (a, b) {
      return new Date('1970/01/01 ' + a) - new Date('1970/01/01 ' + b);
      });
      
      //Test Sorted Array
      console.log(times);
      
      var testTime = "05:00 PM";
      
      function findNearestTime(times, currentTime) {
      
      //Copy given array to new array
      var allTimes = times.slice();
      
      //Push current time to new arrray
      allTimes.push(currentTime);
      
      //Sort New array
      allTimes.sort(function (a, b) {
      return new Date('1970/01/01 ' + a) - new    Date('1970/01/01 ' + b);
      });
      
      //Nearest time will be either the item to the left or to the right of currentTime since array is sorted
      //Now we just find which one is the closest
      var indexOfCurrent = allTimes.indexOf(currentTime);
      
      if (indexOfCurrent == 0) { //if current is first element, nearest will be item 
      //after first element
      return allTimes.slice(indexOfCurrent + 1, indexOfCurrent + 2 );
      }else if (indexOfCurrent == allTimes.length - 1) { //current is last one, 
      //nearest will be the item before current
      return allTimes.slice(allTimes.length - 2, indexOfCurrent);
      }else { //if neither case above, this is where magic happens
      //Find the diff between left/right adjacent element and the current element in the new sorted array 
      var currTime = new Date("01/01/2018 " + currentTime).getHours();
      
      var currTimeLower = new Date("01/01/2018 " + allTimes.slice(indexOfCurrent - 1, 
      indexOfCurrent)).getHours();
      
      var currTimeUpper = new Date("01/01/2018 " + allTimes.slice(indexOfCurrent + 1, 
      indexOfCurrent + 2)).getHours();
      
      var leftDiff  = currTime - currTimeLower;
      var rightDiff = currTimeUpper - currTime;
      
      if(leftDiff < rightDiff) {
        return allTimes.slice(indexOfCurrent - 1, indexOfCurrent);
      }
      else {
        return allTimes.slice(indexOfCurrent + 1, indexOfCurrent + 2);
      }
      
      };
      }
      
      console.log(findNearestTime(times, testTime));
      

      这是工作小提琴。我测试了不同的时间并且它有效。 https://jsfiddle.net/b36fxpqr/13/

      【讨论】:

      • 它不适用于以下值:排序数组:12:00 AM,12:00 PM testTime:06:08 PM 最近时间:12:00 PM
      【解决方案6】:

      var arrayofDate =  ["10:00 PM", "08:00 AM", "12:00 AM", "01:00 AM", "12:00 PM", 
           "03:00 AM", "07:00 AM", "06:00 PM"];
      
      var railwayTime = arrayofDate.map((data, key) => {
      	data = parseInt(data.substr(0,2));
      	if(arrayofDate[key].indexOf('PM') !== -1) {
      		data = data + 12;
      	}
      	return data;
      });
      
      var output = closestTime(new Date().getHours(), railwayTime);
      
      document.getElementById('result').innerHTML = arrayofDate[railwayTime.indexOf(output)];
      
      function closestTime (num, arr) {
      	var curr = arr[0];
      	var diff = Math.abs (num - curr);
      	for (var val = 0; val < arr.length; val++) {
      		var newdiff = Math.abs (num - arr[val]);
      		if (newdiff < diff) {
      			diff = newdiff;
      			curr = arr[val];
      		}
      	}
      	return curr;
      }
      &lt;div id="result"&gt;&lt;/div&gt;

      【讨论】:

      • 感谢@Parthipan,上面的代码似乎不起作用,你能修改一下吗?
      【解决方案7】:

      你也可以试试这个,但是没有用更多的测试用例测试过,如果我错了,请纠正我 `

      var a = ["10:00 PM", "08:00 AM", "12:00 AM", "01:00 AM", "12:00 PM","03:00 AM", "07:00 AM", "06:00 PM"]
      var findhour = new Date().getHours()
      var ans = ""
      var arrayNum = ""
      for(i=0;i<a.length;i++){    
         temp = a[i].split(':')
         if (a[i].includes('PM')){
            temp1 = (12 + +temp[0])%24
            document.write(temp1+"\n")
         }else{
            temp1 = temp[0]
            document.write(temp1+"\n")
         }
         if( Math.abs(ans-findhour) > Math.abs(temp1-findhour)){
            ans = temp1
            arrayNum = i;
            console.log(ans)
         }    
      }
      document.write("ans  " + a[arrayNum])
      

      `

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-20
        • 2019-01-16
        • 1970-01-01
        相关资源
        最近更新 更多