First of all, password strength rules like "at least 12 chars, numbers, signs, upper and lowercase" are actually counterproductive — they result in passwords that are only slightly harder to guess but significantly harder to remember, and worse, they also often end up also disallowing passphrases generated by actually secure methods like Diceware.
Their one arguable merit is that they disallow very common weak passwords like "password", "abc123" or "letmein". Alas, preventing a user from choosing these weak but easy-to-remember passwords will typically just result in them choosing the simplest password that the system will accept, like "Password123!", which is still trivially guessable by any half decent password cracking tool (but now the user is much more likely to forget which punctuation symbol they used and whether they put it before or after the number).
(Another arguable historical rationale for such rules is that using a diverse selection of characters allows squeezing a little bit of extra entropy out of a short password, which could be relevant on systems that severely limit password length, like the old Unix DES-crypt scheme from the 1970s that truncated passwords to at most 8 characters. But such archaic password hashing schemes are fundamentally unsafe anyway, and mixing a few punctuation characters into your password will not make them safe. Still, this is likely one reason why such rules were originally introduced and popularized in the first place.)
Anyway, as far as it goes, your math it looks more or less reasonable to me: 3 billion seconds is about 95 years, so if testing a single password takes 3 seconds on a fast CPU, a password with about 30 bits of entropy (i.e. chosen uniformly at random from among $2^{30} \approx$ 1 billion possibilities) will take 95 CPU-years, which most attackers may consider too much effort. That said, however:
Password cracking is an embarrassingly parallel task, so an attacker willing to dedicate 95 CPU cores to it will shorten the time to just one year. With 5000 cores (which could be easily within reach of e.g. even a fairly small botnet or a server farm) it comes down to one week.
Also remember that processors still continue to get faster (and/or more parallel) and RAM prices still keep going down. Not only does this mean that the time cost of cracking any specific password hash goes down over time, but you also cannot assume that all your users have the latest and greatest CPUs, whereas any decently motivated attacker probably does have access to those, or at least to something reasonably close. Some of your users might be (at least occasionally) using 10 or 20 year old devices with slow CPUs and limited memory, and they'll want to be able to log in using them; an attacker with a botnet will have plenty of newer devices at their disposal.
Three seconds is already a rather awkwardly long time to wait for your password to be accepted. For infrequent use it can be fine, but do you really want to wait that long every time you log in to a website or return to your workstation from a bathroom break? I've seen one second listed as the maximum delay that most users are likely to find acceptable, and that's probably pushing it a bit. Personally, I wouldn't aim much higher than 0.3 to 0.5 seconds.
If you'd like to try a quick experiment, count how many times you have to enter a password (even a prefilled one) or a PIN code per day. Then try counting slowly ("1 mississippi, 2 mississippi, 3 mississippi") to three before pressing enter each time. See how long it takes before you get tired of those pauses.
In any case, for authenticating to a remote server such as a website, even 0.3 seconds of key stretching per login is really only feasible if you can do the work on the client. If you try to do the kind of slow and memory-intensive hashing you suggest on the server side, anyone can bring your server to its knees with a trivial denial-of-service attack just by having a bot try to log in with random usernames and passwords a couple of times a second. Heck, you could probably do that even without a bot just by repeatedly clicking the login button.
With the Web Crypto API and/or WebAssembly implemented in modern browsers, it would be possible for a website to do key stretching on the client side. I haven't seen any standards or widely used implementations for this, though, and while doable in principle, it has some nontrivial security and usability pitfalls that any custom implementation would need to be careful to avoid. Also, it basically makes logging in impossible for users who cannot or will not run JavaScript, as any alternative fallback mechanism could also be abused by attackers. So, at least for a while now, we're still mostly stuck with server-side password hashing.
Summer2020
is still not acceptable. $\endgroup$