I understand that the Date object in the sandbox is a custom one that accepts an integer, which I understood to return a timestamp that’s a given number of milliseconds before the current time - but it doesn’t seem to work that way.
Here’s some code I have in a provision:
const now = Date.now();
const hourly = Date.now(60 * 60 * 1000);
log(`now: ${now}`);
log(`hourly: ${hourly}`);
The output from one run is:
now: 1755696053987
hourly: 1755694283774
Those timestamps are a little under half an hour apart. Another run gives:
now: 1755696223424
hourly: 1755696043059
Three minutes apart.
Where am I going wrong, or misunderstanding? I realise as I’m typing this that I could just say const hourly = now - (60 * 60 * 1000)
, but what’s the purpose of the custom Date.now() method?
Date.now()
is not really “now”. It when the session started.
Date.now(60_000)
is really now - 60 thousand milliseconds.
I am seeing the timestamp issue and I’ve created a test case and escalated this.
1 Like
Hi @westnet-paul,
Here is an explanation from engineering:
When you pass an argument to Date.now(), there’s actually more to it than simply subtracting the given value from the current time. It provides two additional guarantees:
-
The returned value should always be the same during the interval of time specified by the argument (i.e. step function). This ensures that when you’re refreshing multiple parameters periodically, they all get refreshed at the same time. Whereas using a naive approach, different parameters may be refreshed at different times depending on when each was last refreshed.
-
The point in time in which the *step* happens (i.e. time offset) is randomized per device. This is to ensure even load distribution over on the server.
Attached is a quick sketch to illustrate how this would look like if you were to plot the values over time. The black line represents Date.now(), the grey line represents Date.now() - interval, and the red and blue lines represent Date.now(interval) for two different devices.
Ohh, that’s interesting. OK, I need to wrap my head around that and figure out how best to apply it to our implementation.
Thanks for the detailed explanation.