0

Consider following code,

// Code from https://stackoverflow.com/a/66035934/14659574
const getRandomTime = (offsetHour = 0, rangeInHours = 2) => {
  const curTicks = Date.now() + 0 * (offsetHour*60*60*1000);
  const addTicks = (Math.random()*rangeInHours)*60*60*1000;
  
  return new Date(curTicks + addTicks);

};

console.log((new Date()));
for(let i=0; i<10;i++) {
  console.log( getRandomTime(1, 2+i));
}

It doesn't respect the range instead it returns random time exceeding the range. I want a random time within a range.

For example, Let's say I want a random time that's 2 hours from now but this function gives me values like 5 hours from now.

The code is taken from my previous question. It's looks like the author of the answer is inactive so I decided to make a follow up question.

I have dyscalculia and unable to debug this. I even tried to label the numbers but it not going anywhere.

What's the wrong with this code?

jeffbRTC
  • 1,941
  • 10
  • 29
  • I attempted to explain the function with concrete examples but I don't know exactly how dyscalculia works. If you could take a look and let me know if you understand or if anything needs clarifying I can try and break it down with better examples – Jordan Apr 11 '21 at 14:24
  • Tangential: what's the point of the "curTicks" math? You're always adding 0. – Dave Newton Apr 11 '21 at 14:26
  • That's the bug @DaveNewton. Doing so prevents the offset from being applied and as a result it's impossible to change the timezone from UTC – Jordan Apr 11 '21 at 15:07
  • @Jordan I know :) It's why I asked. – Dave Newton Apr 11 '21 at 17:00
  • @DaveNewton Do you know why below answer outputs times that's less than NOW? – jeffbRTC Apr 11 '21 at 18:47
  • @jeffbRTC I don't believe that it does (or that it can). If you add anything (positive) to the current time it will always be after the current time; that's just how addition works. https://codesandbox.io/s/stoic-archimedes-6j25k?file=/src/index.js AFAICT you're not taking TZs into consideration. – Dave Newton Apr 12 '21 at 15:53
  • @DaveNewton I was told by Jordan to use UTC time offset for my timezone for the offset parameter. My timezone is EST so I put -5 there and it giving me values that's less than now. – jeffbRTC Apr 12 '21 at 16:08
  • @jeffbRTC Well yeah. If you subtract five hours from the current time it'll be less than now. I believe you are confusing "the time" with the *representation* of that time. Now is now, no matter what TZ you're in. But if I want to *represent* that time then TZ matters. – Dave Newton Apr 12 '21 at 16:11
  • @DaveNewton No. Jordan said that to make "curTicks" to use my local timezone, I have to set the offset to UTC offset of my timezone. However `new Date(curTicks + addTicks)` returns time that's less than NOW. – jeffbRTC Apr 12 '21 at 16:15
  • @DaveNewton I want a time that's more than now in my timezone so I could use it in setTimeout and I don't know how to make this function to return time that's more than now in my timezone. – jeffbRTC Apr 12 '21 at 16:16
  • @jeffbRTC ... `Date.now()` does not have a TZ. Epoch times do not have TZs: they are an absolute measure of time from a given starting point (which is based on a UTC timestamp). Look at the code I linked to: it's the *representation* of the time that matters. Using your original code (minus the inexplicable multiply-by-zero) I take `Date.now()`, add the random hours to it, and display it in my local TZ (EDT). The time is greater than now because it has to be, because I'm adding a positive offset. – Dave Newton Apr 12 '21 at 16:19
  • @DaveNewton I don't understand anything you say but it looks like setting 1 as parm to offset works. Hard stuff! – jeffbRTC Apr 12 '21 at 16:25
  • @DaveNewton Actually, ASM more easier than this.. – jeffbRTC Apr 12 '21 at 16:27
  • @jeffbRTC :shrug: Using an "offset of one" just means your random times will always be at `now + 1 hour`, e.g., you'll never get a random time that's a half-hour from now. If that's fine, then great. The underlying confusion between what a timestamp is, and the difference between it and its local representation is the issue here. – Dave Newton Apr 12 '21 at 16:29
  • @DaveNewton if it add 1 hour to now then why zero didn't work earlier? – jeffbRTC Apr 12 '21 at 16:31
  • @jeffbRTC re-:shrug: Maybe your local TZ is incorrect, I don't know. Again, please see my code--I changed the offset in the loop to zero and it works just fine. [Here's a gist with the code and output](https://gist.github.com/davelnewton/891787ce7a70005521cd661dc943ca66) – Dave Newton Apr 12 '21 at 16:38
  • @DaveNewton Jordan sent me wild. Okay, it works. – jeffbRTC Apr 12 '21 at 16:57
  • @DaveNewton 0 didn't work before because of 0 * then and Jordan sent me wild by having to set -5 to offset. It's even his comments that it should be from now even if I set -5. Ahaha – jeffbRTC Apr 12 '21 at 16:59
  • @DaveNewton See, `console.log("Up to one hour from now: ",getRandomTime(-5, 1));` – jeffbRTC Apr 12 '21 at 16:59

1 Answers1

0

I believe the bug is in this part: Date.now() + 0 * (offsetHour * 60 * 60 * 1000);.

By multiplying the offset hour by zero, you are effectively resetting it to zero and negating the offset.

As a result, it's not possible to change the starting point from UTC.

With 0 * removed from the method, it works as intended:

const getRandomTime = (offsetHour = 0, rangeInHours = 2) => {
  // Removed the offending 0 *
  const curTicks = Date.now() + (offsetHour * 60 * 60 * 1000);
  const addTicks = (Math.random() * rangeInHours) * 60 * 60 * 1000;

  return new Date(curTicks + addTicks);

};

// Prints a time between UTC-5 and 1 hour from then.
console.log("Up to one hour from now: ",getRandomTime(-5, 1));

// Prints a time between UTC-5 and 2 hours from then.
console.log("Up to two hours from now: ",getRandomTime(-5, 2));

// Example continues
console.log("Up to three hours from now: ",getRandomTime(-5, 3));
console.log("Up to four hours from now: ",getRandomTime(-5, 4));
Jordan
  • 2,245
  • 6
  • 19
  • The author of original answer mentioned in comments that the first param just allows you to get a random time for a future date. Passing 0 is effectively a random time from now() – jeffbRTC Apr 11 '21 at 14:46
  • Yes. The reason it is different if you pass 0 to the function is that the function uses UTC time. What is your timezone? Then when you log `new Date()` and compare it, you are seeing the time in your local time. – Jordan Apr 11 '21 at 14:51
  • Even after setting offset to `-5`, I'm getting values like 2021-04-12T00:38:19.674Z – jeffbRTC Apr 11 '21 at 14:51
  • My timezone is `EST` so UTC -5 and I call `getRandomTime(-5, 2))` and it return times that not fit within the range – jeffbRTC Apr 11 '21 at 14:53
  • Try removing `+ 0 * ` from the method. When multiplying by zero, you invalidate the offset. I will update my answer one sec – Jordan Apr 11 '21 at 14:53
  • @jeffbRTC See my comment on the question. – Dave Newton Apr 11 '21 at 14:56
  • I just did. Check my updated answer. I believe there was a bug after all that was preventing you from changing the offset. It should work now if you put -5 as the offset. – Jordan Apr 11 '21 at 14:57
  • @DaveNewton I saw it but I have no idea either! – jeffbRTC Apr 11 '21 at 14:57
  • @Jordan I just did what you said but it giving me values like `2021-04-13T00:44:57.118Z` – jeffbRTC Apr 11 '21 at 14:58
  • @Jordan Please try to run your code 10-20 times using a loop perhaps 100 times, you will see it outputs values that not fit within range. – jeffbRTC Apr 11 '21 at 15:00
  • I believe it works absolutely fine for me. For example using UTC -5 I'm getting outputs like this: `Up to one hour from now: 2021-04-11T10:45:28.127Z`. No matter how much I spam it, it's never exceeding an hour from now. Did you check my new answer where I've changed it to fix the bug? Can you post the exact way you are runnin – Jordan Apr 11 '21 at 15:03
  • https://imgur.com/P2x69o8 you can see an output of running it in a loop here. This was running the method in my answer with the params `getRandomTime(-5, 1)` – Jordan Apr 11 '21 at 15:05
  • @Jordan I do this in browser and it prints values less than what time now is, ` for(let i = 0; i < 200; i++) { let date = getRandomTime(-5, 10).toString(); console.log(date) }` so I see strings like `Sun Apr 11 2021 06:52:16 GMT-0400 (Eastern Daylight Time) ` – jeffbRTC Apr 11 '21 at 15:20
  • @Jordan Yes, I use your code on your new answer. It prints values that's less than now means my time is 12 PM it prints 09 AM 08 AM etc – jeffbRTC Apr 11 '21 at 16:06
  • @Jordan I believe the offset is causing it. – jeffbRTC Apr 11 '21 at 16:26