在Javascript中每隔X分钟生成一次数组(作为字符串)

时间:2021-06-23 01:07:38

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:

我试图在整个24小时内每隔X分钟创建一个时间数组(字符串,而不是Date对象)。例如,对于5分钟的间隔,阵列将是:

['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:

我的快速而肮脏的解决方案是使用3个嵌套for循环:

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 thats:

这会输出所需的结果,但我想知道是否有更优雅的解决方案。有没有办法做到这一点:

  • more readable
  • 更具可读性
  • less time complex
  • 减少时间复杂

10 个解决方案

#1


13  

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:

如果间隔仅以分钟[0-60]设置,则评估以下解决方案,无需创建日期对象并在单循环中:

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;
}

#2


10  

Allocating the resulting array to avoid the overhead of push, parameter validation and locale specifics notwithstanding:

分配结果数组以避免推送,参数验证和区域设置细节的开销,尽管如此:

function generate_series(step) {
    var dt = new Date(1970, 0, 1, 0, 0, 0, 0),
        rc = [];
    while (dt.getDate() == 1) {
        rc.push(dt.toLocaleTimeString('en-US'));
        dt.setMinutes(dt.getMinutes() + step);
    }
    return rc;
}

Here's a fiddle https://jsfiddle.net/m1ruw1x6/35/

这是一个小提琴https://jsfiddle.net/m1ruw1x6/35/

#3


5  

You need only one loop, follow this approach

你只需要一个循环,遵循这种方法

var d = new Date(); //get a date object
d.setHours(0,0,0,0); //reassign it to today's midnight

Now keep adding 5 minutes till the d.getDate() value changes

现在继续添加5分钟直到d.getDate()值更改

var date = d.getDate();
var timeArr = [];
while ( date == d.getDate() )
{
   var hours = d.getHours();
   var minutes = d.getMinutes();
   hours = hours == 0 ? 12: hours; //if it is 0, then make it 12
   var ampm = "am";
   ampm = hours > 12 ? "pm": "am";
   hours = hours > 12 ? hours - 12: hours; //if more than 12, reduce 12 and set am/pm flag
   hours = ( "0" + hours ).slice(-2); //pad with 0
   minute = ( "0" + d.getMinutes() ).slice(-2); //pad with 0
   timeArr.push( hours + ":" + minute + " " + ampm );
   d.setMinutes( d.getMinutes() + 5); //increment by 5 minutes
}

Demo

演示

#4


5  

The following is massively flexible with the help of Moment.js.

在Moment.js的帮助下,以下内容非常灵活。

This code uses

此代码使用

There's no error handling, so you can pass in stupid parameters, but it gets the point across. :-D

没有错误处理,所以你可以传入愚蠢的参数,但它得到了重点。 :-D

The desiredStartTime parameter takes a time in hh:mm format.

desiredStartTime参数需要hh:mm格式的时间。

The period parameter accepts any of the moment.duration inputs. 在Javascript中每隔X分钟生成一次数组(作为字符串)

period参数接受任何moment.duration输入。

const timelineLabels = (desiredStartTime, interval, period) => {
  const periodsInADay = moment.duration(1, 'day').as(period);

  const timeLabels = [];
  const startTimeMoment = moment(desiredStartTime, 'hh:mm');
  for (let i = 0; i <= periodsInADay; i += interval) {
    startTimeMoment.add(i === 0 ? 0 : interval, period);
    timeLabels.push(startTimeMoment.format('hh:mm A'));
  }

  return timeLabels;
};

/* A few examples */
const theDiv = document.getElementById("times");
let content;

content = JSON.stringify(timelineLabels('18:00', 2, 'hours'))
theDiv.appendChild(document.createTextNode(content));
theDiv.appendChild(document.createElement("p"));

content = JSON.stringify(timelineLabels('06:00', 30, 'm'))
theDiv.appendChild(document.createTextNode(content));
theDiv.appendChild(document.createElement("p"));

content = JSON.stringify(timelineLabels('00:00', 5, 'minutes'))
theDiv.appendChild(document.createTextNode(content));
theDiv.appendChild(document.createElement("p"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>

<div id="times"></div>

#5


1  

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

你可以使用单个for循环,while循环,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


1  

Manipulating with a date as with integer and using single loop:

使用整数和使用单循环操作日期:

var interval = 5 * 60 * 1000; //5 minutes 
var period = 24 * 60 * 60 * 1000; //dat period

//just converts any time to desired string
var toString = function toString(time){  
  var h = time.getHours();
  var m = time.getMinutes();
  var p = h >= 12 ? "PM" : "AM";
  h = h || 12;
  h = h > 12 ? h - 12 : h;  
  return ("0" + h).slice(-2) + ":" + ("0" + m).slice(-2) + " " + p;
}

//start time
var time = new Date(2010, 0, 1);

//resulting array
var times = [];

for ( var t = +time; t < +time + period; t += interval){  
  var d = toString(new Date(t));  
  times.push(d);
}

#7


1  

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

在任何情况下,您都需要执行O(N)操作来枚举数组元素。但是,您可以迭代Date对象本身。

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

演示

#8


1  

Loops are unnecessary in this case.

在这种情况下,循环是不必要的。

ES6

//Array.from, only supported by Chrome 45+, Firefox 32+, Edge and Safari 9.0+
//create an array of the expected interval
let arr = Array.from({
  length: 24 * 60 / 5
}, (v, i) => {
  let h = Math.floor(i * 5 / 60);
  let m = i * 5 - h * 60;
  //convert to 12 hours time
  //pad zero to minute
  if (m < 10) {
    m = '0' + m;
  }
  let label = 'AM';
  if (h > 12) {
    label = 'PM';
    h -= 12;
  }
  if (h === 0) {
    h = 12;
  }
  return h + ':' + m + ' ' + label;
});

document.body.textContent = JSON.stringify(arr);

Wider browser support

var arr = Array.apply(null, {
  length: 24 * 60 / 5
}).map(function(v, i) {
  var h = Math.floor(i * 5 / 60);
  var m = i * 5 - h * 60;
  if (m < 10) {
    m = '0' + m;
  }
  var label = 'AM';
  if (h > 12) {
    label = 'PM';
    h -= 12;
  }
  if (h === 0) {
    h = 12;
  }
  return h + ':' + m + ' ' + label;
});

document.body.textContent = JSON.stringify(arr);

#9


1  

My solution with emphasize on readability. It first creates objects that represent correct times and then formats them to strings. JsFiddle https://jsfiddle.net/6qk60hxs/

我的解决方案强调可读性。它首先创建表示正确时间的对象,然后将它们格式化为字符串。 JsFiddle https://jsfiddle.net/6qk60hxs/

var periods = ['AM', 'PM'];
var hours = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
var minutes = ["00", "05", 10, 15, 20, 25, 30, 35, 40, 45, 50, 55];


timeObj = add([{}], "p", periods);
timeObj = add(timeObj, "h", hours);
timeObj = add(timeObj, "m", minutes);

times = []
for (t of timeObj) {
  times.push(t.h + ':' + t.m + ' ' + t.p);
}

console.log(times)

function add(tab, prop, val) {
  var result = [];
  for (t of tab) {
    for (v of val) {
      tc = _.clone(t);
      tc[prop] = v;
      result.push(tc);
    }
  }
  return result
}

#10


1  

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"]

#1


13  

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:

如果间隔仅以分钟[0-60]设置,则评估以下解决方案,无需创建日期对象并在单循环中:

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;
}

#2


10  

Allocating the resulting array to avoid the overhead of push, parameter validation and locale specifics notwithstanding:

分配结果数组以避免推送,参数验证和区域设置细节的开销,尽管如此:

function generate_series(step) {
    var dt = new Date(1970, 0, 1, 0, 0, 0, 0),
        rc = [];
    while (dt.getDate() == 1) {
        rc.push(dt.toLocaleTimeString('en-US'));
        dt.setMinutes(dt.getMinutes() + step);
    }
    return rc;
}

Here's a fiddle https://jsfiddle.net/m1ruw1x6/35/

这是一个小提琴https://jsfiddle.net/m1ruw1x6/35/

#3


5  

You need only one loop, follow this approach

你只需要一个循环,遵循这种方法

var d = new Date(); //get a date object
d.setHours(0,0,0,0); //reassign it to today's midnight

Now keep adding 5 minutes till the d.getDate() value changes

现在继续添加5分钟直到d.getDate()值更改

var date = d.getDate();
var timeArr = [];
while ( date == d.getDate() )
{
   var hours = d.getHours();
   var minutes = d.getMinutes();
   hours = hours == 0 ? 12: hours; //if it is 0, then make it 12
   var ampm = "am";
   ampm = hours > 12 ? "pm": "am";
   hours = hours > 12 ? hours - 12: hours; //if more than 12, reduce 12 and set am/pm flag
   hours = ( "0" + hours ).slice(-2); //pad with 0
   minute = ( "0" + d.getMinutes() ).slice(-2); //pad with 0
   timeArr.push( hours + ":" + minute + " " + ampm );
   d.setMinutes( d.getMinutes() + 5); //increment by 5 minutes
}

Demo

演示

#4


5  

The following is massively flexible with the help of Moment.js.

在Moment.js的帮助下,以下内容非常灵活。

This code uses

此代码使用

There's no error handling, so you can pass in stupid parameters, but it gets the point across. :-D

没有错误处理,所以你可以传入愚蠢的参数,但它得到了重点。 :-D

The desiredStartTime parameter takes a time in hh:mm format.

desiredStartTime参数需要hh:mm格式的时间。

The period parameter accepts any of the moment.duration inputs. 在Javascript中每隔X分钟生成一次数组(作为字符串)

period参数接受任何moment.duration输入。

const timelineLabels = (desiredStartTime, interval, period) => {
  const periodsInADay = moment.duration(1, 'day').as(period);

  const timeLabels = [];
  const startTimeMoment = moment(desiredStartTime, 'hh:mm');
  for (let i = 0; i <= periodsInADay; i += interval) {
    startTimeMoment.add(i === 0 ? 0 : interval, period);
    timeLabels.push(startTimeMoment.format('hh:mm A'));
  }

  return timeLabels;
};

/* A few examples */
const theDiv = document.getElementById("times");
let content;

content = JSON.stringify(timelineLabels('18:00', 2, 'hours'))
theDiv.appendChild(document.createTextNode(content));
theDiv.appendChild(document.createElement("p"));

content = JSON.stringify(timelineLabels('06:00', 30, 'm'))
theDiv.appendChild(document.createTextNode(content));
theDiv.appendChild(document.createElement("p"));

content = JSON.stringify(timelineLabels('00:00', 5, 'minutes'))
theDiv.appendChild(document.createTextNode(content));
theDiv.appendChild(document.createElement("p"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>

<div id="times"></div>

#5


1  

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

你可以使用单个for循环,while循环,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


1  

Manipulating with a date as with integer and using single loop:

使用整数和使用单循环操作日期:

var interval = 5 * 60 * 1000; //5 minutes 
var period = 24 * 60 * 60 * 1000; //dat period

//just converts any time to desired string
var toString = function toString(time){  
  var h = time.getHours();
  var m = time.getMinutes();
  var p = h >= 12 ? "PM" : "AM";
  h = h || 12;
  h = h > 12 ? h - 12 : h;  
  return ("0" + h).slice(-2) + ":" + ("0" + m).slice(-2) + " " + p;
}

//start time
var time = new Date(2010, 0, 1);

//resulting array
var times = [];

for ( var t = +time; t < +time + period; t += interval){  
  var d = toString(new Date(t));  
  times.push(d);
}

#7


1  

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

在任何情况下,您都需要执行O(N)操作来枚举数组元素。但是,您可以迭代Date对象本身。

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

演示

#8


1  

Loops are unnecessary in this case.

在这种情况下,循环是不必要的。

ES6

//Array.from, only supported by Chrome 45+, Firefox 32+, Edge and Safari 9.0+
//create an array of the expected interval
let arr = Array.from({
  length: 24 * 60 / 5
}, (v, i) => {
  let h = Math.floor(i * 5 / 60);
  let m = i * 5 - h * 60;
  //convert to 12 hours time
  //pad zero to minute
  if (m < 10) {
    m = '0' + m;
  }
  let label = 'AM';
  if (h > 12) {
    label = 'PM';
    h -= 12;
  }
  if (h === 0) {
    h = 12;
  }
  return h + ':' + m + ' ' + label;
});

document.body.textContent = JSON.stringify(arr);

Wider browser support

var arr = Array.apply(null, {
  length: 24 * 60 / 5
}).map(function(v, i) {
  var h = Math.floor(i * 5 / 60);
  var m = i * 5 - h * 60;
  if (m < 10) {
    m = '0' + m;
  }
  var label = 'AM';
  if (h > 12) {
    label = 'PM';
    h -= 12;
  }
  if (h === 0) {
    h = 12;
  }
  return h + ':' + m + ' ' + label;
});

document.body.textContent = JSON.stringify(arr);

#9


1  

My solution with emphasize on readability. It first creates objects that represent correct times and then formats them to strings. JsFiddle https://jsfiddle.net/6qk60hxs/

我的解决方案强调可读性。它首先创建表示正确时间的对象,然后将它们格式化为字符串。 JsFiddle https://jsfiddle.net/6qk60hxs/

var periods = ['AM', 'PM'];
var hours = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
var minutes = ["00", "05", 10, 15, 20, 25, 30, 35, 40, 45, 50, 55];


timeObj = add([{}], "p", periods);
timeObj = add(timeObj, "h", hours);
timeObj = add(timeObj, "m", minutes);

times = []
for (t of timeObj) {
  times.push(t.h + ':' + t.m + ' ' + t.p);
}

console.log(times)

function add(tab, prop, val) {
  var result = [];
  for (t of tab) {
    for (v of val) {
      tc = _.clone(t);
      tc[prop] = v;
      result.push(tc);
    }
  }
  return result
}

#10


1  

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"]