I just ran into a problem with setTimeout and setInterval. Turns out the delay (in milliseconds) for these functions is a 32 bit signed quantity, which limits it to 231-1 ms (2147483647 ms) or 24.855 days.

I was writing an application that needed a 30+ day delay and my setTimeout callbacks were firing instantly. Here's code that demonstrates it:

setTimeout(function () {
  alert("doesn't work - instant alert");
}, 30 * 24 * 3600 * 1000) // 30 days (more than 2^31-1 milliseconds)

This doesn't work. Delay value overflows and setTimeout fires immediately.

I wrote my own setTimeout_ that wraps around native setTimeout and allows large delays:

function setTimeout_ (fn, delay) {
    var maxDelay = Math.pow(2,31)-1;

    if (delay > maxDelay) {
        var args = arguments;
        args[1] -= maxDelay;

        return setTimeout(function () {
            setTimeout_.apply(undefined, args);
        }, maxDelay);

    return setTimeout.apply(undefined, arguments);

This function preserves arguments and you can clearTimeout it within first 24.855 days.

I'll leave getting clearTimeout to work after 24.855 days as an exercise to my blog readers. And I'll also leave getting setInterval to work with large delay as an exercise.

Until next time!