У меня есть множество раз
["10:00 PM", "08:00 AM", "12:00 AM", "01:00 AM", "12:00 PM",
"03:00 AM", "07:00 AM", "06:00 PM"]
Я хочу отсортировать их и найти ближайшее время от текущего времени. Например, предположим, что сейчас 17:00, приведенный выше массив должен вернуть 18:00 в качестве ответа.
я могу отсортировать их с помощью кода ниже
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 чч: мм а?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


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, кажется, что приведенный выше код не работает, не могли бы вы это сделать?
Просто добавьте разницу между текущим часом и часами массива в отдельных 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.info(timeDiff[0].hour);
Рабочая рабочий пример: https://jsbin.com/zojawagiyi/6/edit?js,console
Ваш скрипт не работает! Сейчас 18:08 по моему времени, и когда я добавил элементы 12:00 AM и 12:00 PM, ваша функция получит 12:00 PM как ближайший час вместо 12:00 AM.
Вы также можете попробовать это, но еще не пробовали, поправьте меня, если я ошибаюсь `
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.info(ans)
}
}
document.write("ans " + a[arrayNum])
`
Вы можете использовать приведенное ниже решение, которое сортирует массив и после этого находит ближайшую дату от текущего времени.
Сначала код добавляет текущее время вместе с массивом, а затем получает ближайшую дату.
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.info(dates);
console.info(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);
}Я думаю, что этот код сделает всю работу. Вы можете попробовать это.
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.info(getNearestTime(convertedHours, currentHour));Вот ссылка на jsbin https://jsbin.com/piwuziqeje/edit?js,console
Я попробовал другой / более интуитивный подход, чем те, которые я вижу здесь. Он может быть немного длиннее, чем некоторые, но, на мой взгляд, он более понятен в том, что он делает. Код работает так, как вы можете проверить на скрипке. Вот код:
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.info(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.info(findNearestTime(times, testTime));
Вот рабочая рабочий пример. Я тестировал в разное время, и он работает. https://jsfiddle.net/b36fxpqr/13/
Он не работает со следующими значениями: Сортированный массив: 12:00 AM, 12:00 PM testTime: 18:08 PM Ближайшее время: 12:00 PM
Вы можете попробовать этот небольшой код.
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.info(result);Можете попробовать здесь
Ваш скрипт не работает! Сейчас 18:08 по моему времени, и когда я добавил элементы 12:00 AM и 12:00 PM, ваша функция получит 12:00 PM как ближайший час вместо 12:00 AM.
Это действительно так. Значения времени предполагаются для одной и той же даты. Итак, для 06:08 PM, 12:00 PM наиболее близок к 12:00 AM на ту же дату. Но если вы думаете, что 12:00 AM на следующий день, то 12:00 AM ближе всего. Надеюсь, вы понимаете сценарий.
как насчет значений меридианов?