Сортировать и находить время, ближайшее к текущему времени

У меня есть множество раз

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

Может ли кто-нибудь предложить способ правильно отсортировать его, а также найти ближайшее время с использованием текущего времени? заранее спасибо

как насчет значений меридианов?

Nina Scholz 05.12.2018 13:04

это может быть GMT (+5: 30) или даже UTC, я просто хочу отсортировать его с помощью функции javascript @NinaScholz

Ashwin S 05.12.2018 13:06

Строки, представляющие собой числа, трудно сортировать. Вместо этого вы должны проанализировать их, чтобы упростить сортировку и вычисление. Может, их можно было бы разобрать с помощью Moment.js чч: мм а?

Oliver 05.12.2018 13:55
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
3
1 371
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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 05.12.2018 14:00
Ответ принят как подходящий

Просто добавьте разницу между текущим часом и часами массива в отдельных 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.

genericUser 21.12.2020 17:17

Вы также можете попробовать это, но еще не пробовали, поправьте меня, если я ошибаюсь `

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

genericUser 21.12.2020 17:21

Вы можете попробовать этот небольшой код.

   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.

genericUser 21.12.2020 17:09

Это действительно так. Значения времени предполагаются для одной и той же даты. Итак, для 06:08 PM, 12:00 PM наиболее близок к 12:00 AM на ту же дату. Но если вы думаете, что 12:00 AM на следующий день, то 12:00 AM ближе всего. Надеюсь, вы понимаете сценарий.

Sajeeb Ahamed 21.12.2020 19:48

Другие вопросы по теме