You gave a lot of cases in your question. I think it depends on what you're doing at the time.
If you're writing a function or a class, comments are a way to declare what's supposed to happen with the function. Things like input variables, output type, special behavior, exceptions, etc. IMHO that kind of comment should be written before the actual code is started, in your "code design" phase. Most languages have packages which process those kind of comments into documentation (javadoc, epydoc, POD, etc, so that stuff will be read by users.
If you're making a bit of code work, I think it's OK to wait until you've got it working to put in a comment triumphantly describing your working solution. That kind of comment is only going to get read by a code reviewer.
Then, as others have said, you want to avoid WTF moments, by yourself or others. I once got an attaboy for a comment I made once in an open-source project. The comment was "Yes, I really do want = and not == on that line."