According to calls on Oracle's Metalink, this problem might be caused by dead connections, which cannot be closed. Although 'SHUTDOWN IMMEDIATE' should close all connections, it looks like dead connections are not closed and the database waits for ever (or until you issue the 'SHUTDOWN ABORT' command).
In the cronjob, maybe you can see what connections are still open right before the shutdown statement, what state they're in, etc.
This way you can figure out what connections is causing the problem and see if it is the dead connection philosophy. If this is the case Oracle advises to use the Dead Connection Detection (DCD) feature of net8.
There's no saying how much time you should wait before issuing the shutdown immediate. It all depends on the size of the database, the number of redo logs that should be applied, the number of tablespaces, their size etc. The only way to know when a recovery (always performed in the background) is ready is to read the alert.log
This will show the results of the recovery and indicate whether a database is ready.
For as far as I know, issuing a shutdown immediate should not be a real problem for the database, while recovery will continue after the next startup. So in the case the database should be shutdown and hangs, issue the shutdown abort, do whatever is wanted (you shutted the database for a readson), startup restricted, wait for the recovery to complete and open the database for unrestricted use.
Better is to avoid the problem of an hanging shutdown immediate, by checking if any dead sessions exist and killing them before the shutdown immediate. Or, use Oracle Dead Connection capabilities to avoid dead connections.