0

I try to loop through two given date time. I have to make some calculation on each day of the range. I made a JsBin to setup the problem.

const timeRange1 = ['2019-10-22 14:00:00', '2019-10-22 19:00:00']; 
const timeRange2 = ['2019-10-22 13:30:00', '2019-10-24 10:00:00'];
const timeRange3 = ['2019-10-22 06:00:00', '2019-10-23 23:00:00'];
const timeRange4 = ['2019-10-21 23:00:00', '2019-10-22 01:00:00'];
    
function loop(range) {
  const rangeStart = moment(range[0])
  const rangeEnd = moment(range[1])
  let i = 0
  for (let m = rangeStart; m.diff(rangeEnd, 'days') <= 0; m.add(1, 'days')) {
    i++
  }
  return i
}
  
// Here you can see the expected values and the wrong results. 

console.log(loop(timeRange1)); // 1 - 2
console.log(loop(timeRange2)); // 3 - 3
console.log(loop(timeRange3)); // 2 - 3
console.log(loop(timeRange4)); // 2 - 2
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
RobG
  • 142,382
  • 31
  • 172
  • 209
user3568719
  • 1,036
  • 15
  • 33
  • `const rangeStart = moment(range[0])` is not semantically correct as in the loop you modify *rangeStart*. It makes more sense to use *let* unless you really are going to treat a variable as a constant. – RobG Oct 31 '19 at 10:34

2 Answers2

2

This seems to come from the times. When the time part of the range end is higher than the one from the range start, adding a day does not make the diff lower than 0.

If you truncate them from your moment values, the results are what you expect (use .startOf('day'))

function loop(range) {
  const rangeStart = moment(range[0]).startOf('day')
  const rangeEnd = moment(range[1]).startOf('day')
  let i = 0
  for (let m = rangeStart; m.diff(rangeEnd, 'days') <= 0; m.add(1, 'days')) {
    i++
  }
  return i
}
guillaume.deslandes
  • 1,191
  • 9
  • 12
0

The problem is that diff truncates to an integer, so the loop doesn't stop until the difference is at least 1 day. Consider the first example:

  1. rangeStart initial value: '2019-10-22 14:00:00'
  2. rangeEnd value: '2019-10-22 19:00:00'

1st iteration:

  1. difference: 0.2 days, which truncates to 0 so i is incremented (1)
  2. rangeStart incremented to: '2019-10-23 14:00:00'

2nd iteration:

  1. difference is -0.8 days, which truncates to 0 so i is incremented again (2)
  2. rangeStart incremented to: '2019-10-24 14:00:00'

3rd iteration

  1. difference is -1.8 days, which truncates to -1, so the loop terminates
  2. i is returned (2)

The comparison needs to either:

  1. Account for the truncation
  2. Use decimal days (use 3rd parameter of true)
  3. Set the dates to the same time (e.g. 00:00:00 as suggested by guillaume.deslandes).
RobG
  • 142,382
  • 31
  • 172
  • 209