0
\$\begingroup\$

I need to find a set of hours, starting from now, every 6 hours.

So if now is midnight, I want [ 0, 6, 12, 18 ].
If now is 15h (3pm), I want [ 15, 21, 3, 9 ]

For now I have brute-forced it:

var now = new Date();
var hours = [];
var h = now.getHours();
// add current hour (tomorrow)
hours.push(h);

// to add 6 hours
var inXh = function(toAdd) {
    var inh = h + toAdd;
    if (inh >= 24) { inh = inh - 24; }
    return inh;
}; 

// add in 6 hours
hours.push(inXh(6));
// add in 12 hours
hours.push(inXh(12));
// add in 18 hours
hours.push(inXh(18));

It's incredibly ugly and verbose, and I'm sure there is a much more clever way to do it, but right now I'm too tired to calculate modulos.

\$\endgroup\$
2
\$\begingroup\$

You are basically calculating the modulo manually by doing

if (inh >= 24) { inh = inh - 24; }

but JavaScript can do it for you, so the inXh() function could be written like this:

var inXh = function(toAdd) {
    return (h + toAdd * 6) % 24;
}

With that, after having declared

var h = new Date().getHours();

you have (at least) two options, choose the one you feel more elegant.

OPTION 1: using for:

var hours = [];
for (var i = 0; i < 4; i++) hours.push(inXh(i));

OPTION 2 (nicer in my opinion): using Array.map():

var hours = [0, 1, 2, 3].map(inXh);

which all together in one line would be

var hours = [0, 1, 2, 3].map(function(toAdd) { return (h + toAdd * 6) % 24; });
\$\endgroup\$
2
\$\begingroup\$

If you want a more general answer you could think about wrapping it into a function where you can specify the starting number, the offset, and the max number and then have it generate the whole set for you. Right now your inXh function depends on h above which will make it difficult to reuse. A more general function would look something like this:

function inXh(start, offset, max) {
    // implementation
}

Now for the implementation. Let's start by thinking about your second example with start=15, offset=6, and max=24. All of the numbers you want can be generated by adding 6 to 15 and then applying mod 24 to the result, the problem is where to begin and end. If you keep adding 6 to 15 you get [15, 21, 27, 33, 39, 45, 51, ...]. Applying mod 24 to these numbers you get [15, 21, 3, 9, 15, 21, 3, ...]. You can see the pattern starts to repeat at 39, which is actually 15 + 24 (or start + max), this makes sense because 24 mod 24 is 0 so we end up back where we started. Using this knowledge and renaming your function to something slightly clearer, you could get something like the following:

function getHourSet(start, offset, max) {
  var result = [];
  for (var i = start; i < start + max; i = i + offset) {
    result.push(i % max);
  }
  return result;
}

Now your usage code is also much easier:

var now = new Date();
var hours = getHourSet(now.getHours(), 6, 24);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.