-2

I have a time string array like this:

[
  { from: "07:00", to: "10:00" },
  { from: "12:00", to: "15:00" },
  { from: "16:00", to: "20:00" },
  { from: "22:00", to: "02:00" },
]

The code is then given a time, e.g. "13:00", and need to work out if it is between any of these times. Just wondering what's the best way to do this? I tried to parse them to a date object but that feels wrong as it needs to work across midnight.

net-junkie
  • 575
  • 1
  • 7
  • 10
  • You could try parsing time of day into minutes, which gives you a number: `(hours * 60) + minutes`. This would make them easy to compare. – Balázs Édes Apr 18 '21 at 11:19
  • yeah, but don't think that'll work when 2 times are across midnight e.g. 23:00 to 02:00, and compare 01:00. – net-junkie Apr 18 '21 at 11:35
  • If the first number is greater than second, you are crossing a day, you need to accommodate that in how you are calculating. If you need to be able to compute time spans across multiple days, you need more information, time is not enough. – Balázs Édes Apr 18 '21 at 11:41

4 Answers4

2

With a "normal" range (from < to), our time should be greater than from AND less than to. With a "rollover" range (from > to), the time should be greater than from OR less than to.

let inTimeRange = (t, {from, to}) => (from < to) 
     ? (t > from && t < to) 
     : (t > from || t < to);

ranges = [
    {from: "07:00", to: "10:00"},
    {from: "12:00", to: "15:00"},
    {from: "16:00", to: "20:00"},
    {from: "22:00", to: "02:00"},
]


test = ['09:00', '11:56', '21:59', '22:03', '01:44', '02:15']

for (t of test)
    console.log(t, ranges.find(r => inTimeRange(t, r)))
georg
  • 211,518
  • 52
  • 313
  • 390
0

So just by going through the list of time-spans and converting the hourly values to numbers (e.g.: 13:00 => 1300) and than comparing your time you can find if your given number is in your time span. And by looking if .to is smaller than .from you know its over midnight.

var list = [
    { from: "07:00", to: "10:00" },
    { from: "12:00", to: "15:00" },
    { from: "16:00", to: "20:00" },
    { from: "22:00", to: "02:00" },
];

//the time you want to look after
var find = "01:00";

//going through times
for (times in list) {
  //
  var from = list[times].from;
  var to = list[times].to;
  //
  if (find <= to) {
    //for over midnight
    if (to < from) {
      console.log("find:", find, "is between", list[times]);
    }
    //regular between
    else if (find >= from && find <= to) {
      console.log("find:", find, "is between", list[times]);
    }
  }
}
RobG
  • 142,382
  • 31
  • 172
  • 209
proto
  • 31
  • 5
  • You say "*…and converting the hourly values to numbers*" but don't actually do that. Times in HH:mm format compare lexically so there's no need to convert to Number (as your code shows). ;-) – RobG Apr 19 '21 at 03:29
0

here is a working example:

const times = [
  { from: "07:00", to: "10:00" },
  { from: "12:00", to: "15:00" },
  { from: "16:00", to: "20:00" },
  { from: "22:00", to: "02:00" }
];

function checkBetweenTimes(timesArr, timeToCheck) {
  timeToCheck = timeToCheck.replace(":", "");
  for (const time of timesArr) {
    time.from = time.from.replace(":", "");
    time.to = time.to.replace(":", "");
    if (timeToCheck >= time.from && timeToCheck <= time.to) {
      // make a array from time wich is currently "1300" into [1,3,0,0]
      timeToCheck = timeToCheck.split("");
      time.from = time.from.split("");
      time.to = time.to.split("");

      // add ":" at index 2 to make it a time again [1,3,:,0,0]
      timeToCheck.splice(2, 0, ":");
      time.from.splice(2, 0, ":");
      time.to.splice(2, 0, ":");

      // join the array back to "13:00"
      timeToCheck = timeToCheck.join("");
      time.from = time.from.join("");
      time.to = time.to.join("");
      return `${timeToCheck} is in between ${time.from} and ${time.to}`;
    }
  }
}

console.log(checkBetweenTimes(times, "13:00"));


Deniz
  • 1,435
  • 14
  • 29
0

function isTimeBetween(_from, _to, _time) {
    var time = +_time.replace(':', ""),
        from = +_from.replace(':', ""),
        to = +_to.replace(':', "");
    if (from > 1200 && to < 1200) {
        to += 2400;
        if (time < 1200) {
            time += 2400;
        }
    }
    return from <= time && to >= time;
}

// Test
(function () {

    const times = [
        { from: "07:00", to: "10:00" },
        { from: "12:00", to: "15:00" },
        { from: "16:00", to: "20:00" },
        { from: "22:00", to: "02:00" },
    ];

    function log(str) {
        document.body.insertAdjacentHTML('beforeend', str + '<br/>')
    }

    var h = 0;
    log('>>> Test Start');
    while (h < 24) {
        log('--------------------');
        let time = `${String(h).padStart(2, "0")}:00`;
        let found = times.filter(t => isTimeBetween(t.from, t.to, time));
        if (found.length > 0) {
            found.forEach((t) => log(`${time} is between ${t.from} and ${t.to}`));
        } else {
            log(`${time} is not between any of specified intervals`)
        }
        h++;
    }
    log('--------------------');
    log('>>> Test End');
}());
Wazeed
  • 1,230
  • 1
  • 8
  • 9