Generate array of times (as strings) for every X m

2020-05-17 04:15发布

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条回答
欢心
2楼-- · 2020-05-17 04:47

if you have access to moment, you can always do something like this:

const locale = 'en'; // or whatever you want...
const hours = [];

moment.locale(locale);  // optional - can remove if you are only dealing with one locale

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

the result is the following array:

["12:00 AM", "12:30 AM", "1:00 AM", "1:30 AM", "2:00 AM", "2:30 AM", "3:00 AM", "3:30 AM", "4:00 AM", "4:30 AM", "5:00 AM", "5:30 AM", "6:00 AM", "6:30 AM", "7:00 AM", "7:30 AM", "8:00 AM", "8:30 AM", "9:00 AM", "9:30 AM", "10:00 AM", "10:30 AM", "11:00 AM", "11:30 AM", "12:00 PM", "12:30 PM", "1:00 PM", "1:30 PM", "2:00 PM", "2:30 PM", "3:00 PM", "3:30 PM", "4:00 PM", "4:30 PM", "5:00 PM", "5:30 PM", "6:00 PM", "6:30 PM", "7:00 PM", "7:30 PM", "8:00 PM", "8:30 PM", "9:00 PM", "9:30 PM", "10:00 PM", "10:30 PM", "11:00 PM", "11:30 PM"]
查看更多
三岁会撩人
3楼-- · 2020-05-17 04:49
function timegenerate(starth,startm,endh,endm,interval)
    {
        times=[]
        size= endh>starth ? endh-starth+1 : starth-endh+1
        hours=[...Array(size).keys()].map(i => i + starth);
        for (hour in hours)
        {
            for (min = startm; min < 60; min += interval) 
            {
                startm=0
                if ((hours.slice(-1)[0] === hours[hour]) && (min > endm))
                {
                    break;
                }
                if (hours[hour] > 11 && hours[hour] !== 24 )
                {
                    times.push(('0' + (hours[hour]%12 === 0 ? '12': hours[hour]%12)).slice(-2) + ':' + ('0' + min).slice(-2) + " " + 'PM');
                }
                else
                {
                    times.push(('0' +  (hours[hour]%12 === 0 ? '12': hours[hour]%12)).slice(-2) + ':' + ('0' + min).slice(-2) + " " + 'AM');
                }
            }
        }
        return times
    }

    starthour=13
    startminute=30
    endhour=23
    endminute=30
    interval=30
    console.log(timegenerate(starthour,startminute,endhour,endminute,interval))
查看更多
Ridiculous、
4楼-- · 2020-05-17 04:49

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')
  );
}
查看更多
Deceive 欺骗
5楼-- · 2020-05-17 04:50

You could use a single for loop, while loop , Array.prototype.map(), Array.prototype.concat() , String.prototype.replace()

var n = 0,
  min = 5,
  periods = [" AM", " PM"],
  times = [],
  hours = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];

for (var i = 0; i < hours.length; i++) {
  times.push(hours[i] + ":" + n + n + periods[0]);
  while (n < 60 - min) {
    times.push(hours[i] + ":" + ((n += 5) < 10 ? "O" + n : n) + periods[0])
  }
  n = 0;
}

times = times.concat(times.slice(0).map(function(time) {
  return time.replace(periods[0], periods[1])
}));

console.log(times)

查看更多
时光不老,我们不散
6楼-- · 2020-05-17 04:53

If the interval is only to be set in minutes[0-60], then evaluate the below solution w/o creating the date object and in single loop:

var x = 5; //minutes interval
var times = []; // time array
var tt = 0; // start time
var ap = ['AM', 'PM']; // AM-PM

//loop to increment the time and push results in array
for (var i=0;tt<24*60; i++) {
  var hh = Math.floor(tt/60); // getting hours of day in 0-24 format
  var mm = (tt%60); // getting minutes of the hour in 0-55 format
  times[i] = ("0" + (hh % 12)).slice(-2) + ':' + ("0" + mm).slice(-2) + ap[Math.floor(hh/12)]; // pushing data in array in [00:00 - 12:00 AM/PM format]
  tt = tt + x;
}

console.log(times);

查看更多
够拽才男人
7楼-- · 2020-05-17 04:54

In any case you need to do O(N) operations to enumerate array elements. However, you could iterate through Date objects itself.

function timeArr(interval) //required function with custom MINUTES interval
{
  var result = [];
  var start = new Date(1,1,1,0,0);
  var end = new Date(1,1,2,0,0);
  for (var d = start; d < end; d.setMinutes(d.getMinutes() + 5)) {
      result.push(format(d));
  }

  return result;
}

function format(inputDate) // auxiliary function to format Date object
{
    var hours = inputDate.getHours();
    var minutes = inputDate.getMinutes();
    var ampm = hours < 12? "AM" : (hours=hours%12,"PM");
    hours = hours == 0? 12 : hours < 10? ("0" + hours) : hours;
    minutes = minutes < 10 ? ("0" + minutes) : minutes;
    return hours + ":" + minutes + " " + ampm;
}

Demo

查看更多
登录 后发表回答