Look at things in perspective: this verification email is to verify that the user's email address is valid because the user received the verification email and the activation key sent with the email matches the one generated and stored on the server.
Therefore, what you are trying to do is to prevent say, a spammer from registering many users with fake email addresses, and then spoofing the activation key in order to activate the accounts.
So, we assume that the attacker knows the algorithm, i.e., if you write this:
$act_key = sha1($username.time());
the attacker knows it. Furthermore, the attacker presumably knows the user's username. Therefore, your solution is as good (or as bad) as uniqid, which "gets a prefixed unique identifier based on the current time in microseconds" (and in fact you could have used the username for the prefix).
You can easily fix this by mixing in a secret key before computing the cryptographic hash. This could replace the username, since the username adds nothing that the attacker does not know. For example:
$act_key = sha1(uniqid($secret_key, true));
The secret key itself would presumably be defined in a configuration file separate from your code, e.g., in a file outside of your document root/public html directory.