I previously had this buried in another thread but let me put it here instead, and translate it to the lingua franca, aka Javascript. Thanks to @chipmanaged for nudging me to do this.

First some constants (and a global variable):

```
const log = Math.log // Keep
const exp = Math.exp // Mathematics
const max = Math.max // Beautiful
const round = Math.round
const GAP = 45*60 // Average gap between pings, in seconds
const URPING = 1184083200 // Ur-ping ie the birth of Timepie/TagTime! (unixtime)
const SEED = 666 // Initial state of the random number generator
const IA = 16807 // (7^5) Multiplier used for LCG random number generator
const IM = 2147483647 // (2^31-1) Modulus used for RNG
let state = SEED // Global variable that's the state of the RNG
```

Next the functions for generating random numbers:

```
// Return a random integer in [1,IM-1]; changes the RNG state.
// (This is ran0 from Numerical Recipes and has a period of ~2 billion)
function ran0() { return state = IA * state % IM }
// Return a U(0,1) random number
function ran01() { return ran0()/IM }
// Return a random number drawn from an exponential distribution with mean = GAP
function exprand() { return -GAP * log(ran01()) }
```

And finally the functions to compute the next ping time:

```
// Take previous ping time, return random next ping time (unixtime). If the next
// ping is less than 1s after the previous one, artificially push it forward so
// that it's a full second later.
// NB: this has the side effect of changing the RNG state and so should only be
// called once per next ping to calculate, after calling prevping().
function nextping(pung) { return max(pung+1, round(pung+exprand())) }
// Compute the last scheduled ping time before time t
function prevping(t) {
state = SEED
let p = URPING // Starting at the beginning of time, walk forward
let prevp = p // computing next pings until the next ping time is
let prevstate = state // greater than or equal to t
while(p < t) {
prevp = p
prevstate = state
p = nextping(p)
}
state = prevstate
return prevp
}
```

To get the next ping times starting now (say thatās time `t`

), you first call `p = prevping(t)`

. So `p`

is now the most recent ping time, according to the universal ping schedule, before time `t`

. Then keep doing `p = nextping(p)`

and `p`

will always be the upcoming ping time.

PS: In Javascript you get current unixtime in seconds with `Date.now()/1000`

(just `Date.now()`

returns it in milliseconds).