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 arr
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'));
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
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
Allocating the resulting array to avoid the overhead of push, parameter validation and locale specifics notwithstanding:
function generate_series(step) {
const dt = new Date(1970, 0, 1);
const rc = [];
while (dt.getDate() === 1) {
rc.push(dt.toLocaleTimeString('en-US'));
dt.setMinutes(dt.getMinutes() + step);
}
return rc;
}
Here's a demo snippet.
function generate_series(step) {
const dt = new Date(1970, 0, 1);
const rc = [];
while (dt.getDate() === 1) {
rc.push(dt.toLocaleTimeString('en-US'));
dt.setMinutes(dt.getMinutes() + step);
}
return rc;
}
function on_generate_series(step) {
const dt = new Date(1970, 0, 1);
const el = document.getElementById("series")
while (el.firstChild)
el.removeChild(el.firstChild);
const series = generate_series(step);
while (series.length > 0) {
let item = document.createElement("div");
item.innerText = series.shift();
el.appendChild(item);
}
}
<h1 id="title">24 Hour Minute Series</h1>
<input type="number" id="step" value="30" />
<input type="submit" id="byBtn" value="Generate Series" onclick="on_generate_series(parseInt(document.getElementById('step').value,10))" />
<div id="series">
</div>
The following is massively flexible with the help of Moment.js.
This code uses
There's no error handling, so you can pass in stupid parameters, but it gets the point across. :-D
The desiredStartTime
parameter takes a time in hh:mm
format.
The period
parameter accepts any of the moment.duration
inputs.
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>
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')
);
}
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