排序并找到距离当前时间最近的时间

5
我有一个时间数组。
    ["10:00 PM", "08:00 AM", "12:00 AM", "01:00 AM", "12:00 PM", 
     "03:00 AM", "07:00 AM", "06:00 PM"]

我希望能对它们进行排序并找到距离当前时间最近的时间。例如,假设现在是下午5点,上面的数组应该返回下午6点
我可以使用以下代码对它们进行排序。
    let sortedArray = arrayOfData.sort(function (a, b) {
    return parseInt(a.substring(0, 2)) - 
    parseInt(b.substring(0, 2));
    }) 

有人能建议一种正确排序的方法,并找到使用当前时间最接近的时间吗?谢谢提前。


1
子午线值怎么样? - Nina Scholz
可以是GMT (+5:30)或甚至是UTC,我只想用JavaScript函数进行排序@NinaScholz - Ashwin S
字符串形式的数字很难排序。相反,您应该将它们解析为更容易排序和计算的内容。也许您可以使用Moment.js hh:mm a来解析它们? - Oliver
7个回答

4
我认为这段代码可以完成任务。你可以尝试一下。

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


4

只需将当前小时数与数组小时数之间的差异添加到单独的array中,然后按升序进行sort,并从array中获取第一个元素,这将是最合适的时间。

请查看以下片段:

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


你的脚本出了问题!现在是我的时区下午6:08,当我添加12:00 AM和12:00 PM元素时,你的函数将12:00 PM作为最近的小时,而不是12:00 AM。 - genericUser

2
您可以使用下面的解决方案,对数组进行排序,然后找到距离当前时间最近的日期。
首先,代码将当前时间与数组相加,然后获取最近的日期。

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);
}


2
您可以尝试这段小代码。

   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);

您可以在这里尝试。

你的脚本出了问题!现在是我的时区下午6:08,当我添加12:00 AM和12:00 PM元素时,你的函数将12:00 PM作为最近的小时,而不是12:00 AM。 - genericUser
这实际上是正确的。时间值假定为同一日期。因此,对于“06:08 PM”,“12:00 PM”最接近同一日期的“12:00 AM”。但是,如果您认为“12:00 AM”是下一个日期,则“12:00 AM”最接近。我希望您理解这种情况。 - Sajeeb Ahamed

2

我尝试了一种与这里看到的方法不同/更直观的方法。它可能比一些方法稍微长一点,但在我看来,它更清晰地说明了它在做什么。您可以在fiddle中检查代码是否有效。以下是代码:

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 测试时间:06:08 PM 最接近的时间:12:00 PM - genericUser

1

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;
}
<div id="result"></div>


感谢@Parthipan,看起来上面的代码不起作用,你能请修复一下吗? - Ashwin S

0
你也可以尝试这个,但我还没有用更多的测试用例来测试它,如果我错了请纠正我。`

`
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])

`


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接