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!

Comments

October 28, 2015, 06:10

Indeed, 30 days is a very long time for a JS timeout

October 28, 2015, 07:33

Relying on a single process staying up 30 days so a timeout can occur seems crazy. Schedule a job in some external state instead.

Also, JS timeouts are not known for accuracy. I wonder if there'd be any significant drift with a timeout that long.

Craig Permalink
October 28, 2015, 07:29

I think the solution here would be to use some form of job scheduling rather than depend on a single process staying up for 30 days...

October 28, 2015, 17:00

Just out of curiosity: what is the use case where you need 30 days timeout in JavaScript?

October 28, 2015, 18:57

I just build various tools in browsers now. Browser is the new operating system for me. So this tool was monitoring social media and reporting stats every 30 days. I just keep browsers running in VMs for months and never close them (unless they crash or system crashes).

December 02, 2015, 18:50

Good point to make. I believe wraparound is particularly tricky for beginner programmers when they're not overly familiar with how variables actually work on a hardware level. If you've just used var's your whole career, you're likely to be more removed from the hardware and may not be aware of what can seem to be arbitrary limits like this. Cool write up!

Leave a new comment

(why do I need your e-mail?)

(Your twitter name, if you have one. (I'm @pkrumins, btw.))

Type the word "cdrom_494": (just to make sure you're a human)

Please preview the comment before submitting to make sure it's OK.

Advertisements