Jamgreen
Jamgreen

Reputation: 11039

Create array of time points in JavaScript

How can I make an array of time points such that I get ['00:00', '00:15', '00:30', '00:45', '01:00', '01:15', '01:30', '01:45', '02:00', ...]?

I have come up with

const timePoints = new Array(24 * 4).fill(0).map((time, i) => {
  const seconds = i * 15 * 60;
  const minutes = seconds / 60;
  return `${Math.floor(minutes / 60)}:${seconds / 60 % 60}`;
});

console.log(timePoints);

it does work, but I actually want the array to start from the quarter that is closest to the actual time.

So if the clock says 16:35, I want it to start from '16:45', giving me an array ['16:45', '17:00', '17:15', ...].

It might be something like starting by finding the start time, creating a loop that iterates 24*4 times and then extract the hours and minutes separately and add either 0 or 1 to the hours and either add 15 or subtract 45 from the minutes.

But it might be possible to do with a more clever solution

Upvotes: 0

Views: 327

Answers (5)

Thabo Moyo
Thabo Moyo

Reputation: 303

Just amended your original code to use Date class functions. This simplifies it a bit.

new Array(24 * 4).fill(0).map((time, i) => {
        const date = new Date()
        const seconds = i * 15 * 60
        date.setHours(Math.floor(seconds / 60 / 60))
        date.setMinutes((seconds / 60) % 60)
        date.setSeconds(0)
        return date.toTimeString().substring(0, 5)
    })

//output: [ "00:00", "00:15", "00:30", "00:45", "01:00", "01:15", "01:30", "01:45", "02:00", "02:15", … ]

Upvotes: 0

trincot
trincot

Reputation: 350300

You could use reduce and pass the current time as start value. Use toTimeString for extracting the hh:mm format which relieves you from formatting the minutes with 2 digits:

const timePoints = new Array(24 * 4).fill(0).reduce(([arr, d], time) => {
  d.setMinutes(Math.ceil((d.getMinutes() + 1) / 15) * 15);
  return [arr.concat(d.toTimeString().substr(0,5)), d];
}, [[], new Date()])[0];

console.log(timePoints);

Upvotes: 1

Jonathan
Jonathan

Reputation: 9151

You could convert the "actual time" to a number and then do this:

const timePoints = ["00:00", "00:15", "00:30", "00:45", "01:00", "01:15", "01:30", "01:45", "02:00", "02:15", "02:30", "02:45", "03:00", "03:15", "03:30", "03:45", "04:00", "04:15", "04:30", "04:45", "05:00", "05:15", "05:30", "05:45", "06:00", "06:15", "06:30", "06:45", "07:00", "07:15", "07:30", "07:45", "08:00", "08:15", "08:30", "08:45", "09:00", "09:15", "09:30", "09:45", "10:00", "10:15", "10:30", "10:45", "11:00", "11:15", "11:30", "11:45", "12:00", "12:15", "12:30", "12:45", "13:00", "13:15", "13:30", "13:45", "14:00", "14:15", "14:30", "14:45", "15:00", "15:15", "15:30", "15:45", "16:00", "16:15", "16:30", "16:45", "17:00", "17:15", "17:30", "17:45", "18:00", "18:15", "18:30", "18:45", "19:00", "19:15", "19:30", "19:45", "20:00", "20:15", "20:30", "20:45", "21:00", "21:15", "21:30", "21:45", "22:00", "22:15", "22:30", "22:45", "23:00", "23:15", "23:30", "23:45"];

// Helper method to rotate the array.
Array.prototype.rotate = function(n) {
  return this.slice(n, this.length).concat(this.slice(0, n));
}

// Get time as a float here:
var myTime = 19.48;
// Convert the times to floats.
var values = timePoints.map(x => +x.replace(/:/, '.'));

// You can do this to get the next value.
// var next = timePoints[values.findIndex(x => x - myTime > 0)] || timePoints[0];
// console.log(next);

// Find the index for the first value that results in a positive number 
// when you subtract myTime, or take 0 if none can be found.
var nextIndex = Math.max(values.findIndex(x => x - myTime > 0), 0);
// Rotate the array this many positions.
var newArr = timePoints.rotate(nextIndex);

console.log(newArr);

Upvotes: 1

yezzz
yezzz

Reputation: 3020

Another way of doing it with a Date object:

var d = new Date();
// use Math.ceil to always round up
d.setMinutes(Math.round(d.getMinutes() / 15) * 15);
console.log("Rounded datetime: ", d);
var hours,
  minutes,
  arr = [];

for (var i = 0; i < 96; i++) {
  hours = ("0" + d.getHours()).slice(-2);
  minutes = ("0" + d.getMinutes()).slice(-2);
  arr.push(hours + ":" + minutes);
  d.setMinutes(d.getMinutes() + 15);
}
console.log(arr);

Upvotes: 0

Pankaj Shukla
Pankaj Shukla

Reputation: 2672

You can take the hour part and minute part with getHours and getMinutes and with some simple loping it should be possible. Look at the code below:

var hours = new Date().getHours();
var mins = new Date().getMinutes();
var minutes = getClosestQuarter(mins) * 15;

function getClosestQuarter(mins) {
  return Math.floor(mins / 15) + 1;
}
var minPart = minutes - 15;

var ans = [];

for (var i = 0; i < 24 * 4; i++) {
  minPart += 15;
  if (minPart == 60) {
    minPart = 0;
    hours++;
    if (hours > 23) {
      hours = 0;
    }
  }
  ans.push(getTimeString(hours, minPart));
}

function getTimeString(hours, mins) {
  hours = hours ? hours.toString() : '00';
  hours = hours.length == 1 ? '0' + hours : hours;
  mins = mins ? mins.toString() : '00';
  return hours + ':' + mins;
}
console.log(ans);

Upvotes: 1

Related Questions