0

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

2
  • I don't really understand what you are asking. Also what have you tried to get the start time? Commented May 20, 2017 at 14:58
  • Do you mean 'closest to the actual time and after the actual time'? The closest time to 16:35 is 16:30 not 16:45. Commented May 20, 2017 at 15:15

5 Answers 5

1

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

Sign up to request clarification or add additional context in comments.

Comments

1

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

1 Comment

@PankajShukla Changed it
1

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

1 Comment

argl... why wasn't my toTimeString() giving me the leading 0 when I was fiddleing with that... (with .slice(0,5) )
0

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.