Generate array of times (as strings) for every X minutes in JavaScript

Viewed 61822

I'm trying to create an array of times (strings, not Date objects) for every X minutes throughout a full 24 hours. For example, for a 5 minute interval the array would be:

['12:00 AM', '12:05 AM', '12:10 AM', '12:15 AM', ..., '11:55 PM']

My quick and dirty solution was to use 3 nested for loops:

var times = []
  , periods = ['AM', 'PM']
  , hours = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
  , prop = null
  , hour = null
  , min = null; 

for (prop in periods) {
  for (hour in hours) {
    for (min = 0; min < 60; min += 5) {
      times.push(('0' + hours[hour]).slice(-2) + ':' + ('0' + min).slice(-2) + " " + periods[prop]);
    }
  }
}

This outputs the desired result but I'm wondering if there's a more elegant solution. Is there a way to do this that's:

  • more readable
  • less time complex
15 Answers

This snippet generates a range base on locale, so you do not need to handle AM/PM manually. By default, it will use browser language, but you can pass a user-selected one.

function getTimeRanges(interval, language = window.navigator.language) {
    const ranges = [];
    const date = new Date();
    const format = {
        hour: 'numeric',
        minute: 'numeric',
    };

    for (let minutes = 0; minutes < 24 * 60; minutes = minutes + interval) {
        date.setHours(0);
        date.setMinutes(minutes);
        ranges.push(date.toLocaleTimeString(language, format));
    }

    return ranges;
}

console.log('English', getTimeRanges(30, 'en'));
console.log('Russian', getTimeRanges(30, 'ru'));

This is an iteration of Faizan Saiyed's answer.

const startHour = moment().format('k');
const endHour = 22

const arr = () => {
  return Array.from({
  length: endHour - startHour
  }, (v, index) => {
    return [0,15,30,45].map((interval) => {
      return moment({
        hour: index,
        minute: interval
      })
      .add(startHour, 'hours')
      .format('h:mm A')
    })
  }).flat()
}
const getTimes = (increment = 2) => {
  const times = [];
  for (let i = 0; i < 24; i++) {
    times.push({
      value: `${i === 0 || i - 12 === 0 ? 12 : i < 12 ? i : i - 12}:00 ${i < 12 ? 'AM' : 'PM'}`,
      label: `${i === 0 || i - 12 === 0 ? 12 : i < 12 ? i : i - 12}:00 ${i < 12 ? 'AM' : 'PM'}`,
    });
    for (let j = 60 / increment; j < 60; j += 60 / increment) {
      times.push({
        value: `${i === 0 || i - 12 === 0 ? 12 : i < 12 ? i : i - 12}:${Math.ceil(j)} ${i < 12 ? 'AM' : 'PM'}`,
        label: `${i === 0 || i - 12 === 0 ? 12 : i < 12 ? i : i - 12}:${Math.ceil(j)} ${i < 12 ? 'AM' : 'PM'}`,
      });
    }
  }
  return times;
};

The result of this is an array times converted into markup that I place in a <select> object. I found that underscore.js's _.range allows me to step through increments but only as integers. So, I used moment.js to convert to unix time. I needed to iterate over minutes slottime, but other intervals can be accomplished with the multiplier, again in my case 60000 making minutes added to valueOf().

function slotSelect(blockstart, blockend, slottime) {
    var markup = "";
    var secs = parseInt(slottime * 60000); // steps
    var a = parseInt( moment(blockstart).valueOf() ); // start
    var b = parseInt( moment(blockend).valueOf() );
    var times = _.range(a, b, secs);

    _.find( times, function( item ) {
        var appttime = moment(item).format('h:mm a');
        var apptunix = moment(item).format();
        markup += '<option value="'+apptunix+'"> ' + appttime + ' </option>'+"\n";
    });
    return markup;
}

To start list from particular time like 3:00 PM and loop quarterly(every 15 minutes):

const hours = [];
const startHour = 15;

for (let hour = 0; hour < 24; hour++) {
  hours.push(
    moment({ hour })
      .add(startHour, 'hours')
      .format('h:mm A')
  );

  hours.push(
    moment({
      hour,
      minute: 15
    })
      .add(startHour, 'hours')
      .format('h:mm A')
  );

  hours.push(
    moment({
      hour,
      minute: 30
    })
      .add(startHour, 'hours')
      .format('h:mm A')
  );

  hours.push(
    moment({
      hour,
      minute: 45
    })
      .add(startHour, 'hours')
      .format('h:mm A')
  );
}
Related