First, to calm your nerves, no one is "good" at coming up with time estimates for coding projects. Some are better than others, but the bottom line is that software is so unbelievably complex so quickly that getting it all in your head, determining pieces to be done, and figuring out how long that will all take pretty much takes as much time as actually doing it.
In fact, in my experience, it's nearly as difficult to tell how long something took after the fact (hindsight is 20-20? Not in my experience!) as it is to predict it ahead of time. So, don't fret that you're bad at it. It's not like you're unique at that ;-)
My rules:
- NEVER underestimate. Don't be an optimist about how things will turn out. Everyone seems to overestimate their own productivity, and assume that nothing will go wrong. Both of these assumptions are always untrue. (Statistics say they must be right sometimes, but that's not my experience.) This is even more important when sizing things that other people will be implementing.
- When I was first doing estimations, I'd use the 20-60-20 rule. Ok, I don't know if it was a real rule, but I was using it anyway. What it is is that I'd actually come up with three estimates. My optimistic estimate, plus a realistic one, and a worst-case one. I'd then assign weightings of 20, 60, and 20, respectively, and then take the weighted average. (I'd also usually provide all four estimates to my manager - and bold the weighted-average estimate as my "official" estimate.)
- Details. The more detail you can come up with, the more accurate you'll be. Or, if you're missing something, the better chance a coworker will spot it and point it out. "You're missing the integration with the frobnoozer software - how long will that take?" Or they'll disagree with the individual sizings: "Implementing the braznaut feature couldn't possibly be done in less than a week!" "Why don't you just use the Standard Template Library? Should only take a few days that way."
Also, I've found management to appreciate that I've already provided all the justification for the sizing, and they can just forward it to their management as-is. I've gotten a fair bit of airplay with upper management that way.
- Don't forget: meeting about a feature counts as effort in producing it. 8 people in a 1-hour meeting counts as 1 person-day of effort. If you need a meeting to figure out the details, or to co-ordinate multiple people working on it, it's overhead, and needs to be accounted for.
- Also, remember that learning new technology to implement something needs to be accounted for in the sizing. New people on a team will need some time to get up to speed - so they'll be 50-100% slower than their coworkers, and you'll need to have someone spend time working with them to bring them up to speed. The mentor's time needs to be in the sizing, too.
Above all - find a balance between time spent getting an accurate sizing and that accurate sizing. Don't spend two weeks figuring out how much time a project will take when it should be in the 20-30 hour range. On the other hand, something that will take a year to do deserves some extra time spent on it up front.
I've learned to do fast sizings, and I throw in a fudge factor on everything. Usually 25-50% (it used to be closer to 100% until I started getting more accurate on my thumb-suck guesses). These are all just guesses anyway, so a fudge factor seems appropriate ;-) This helps account for things going wrong, for meetings, and other details that I keep forgetting.
Update: last rule: I always round up. Anything over 4 hours becomes 1 day. Anything over 3 days becomes one week. Anything over 3 weeks becomes 1 month. Anything over 7 or 8 months becomes 1 year (let's face it, we're looking so far into the future that it's pure bunk anyway). Anything over 2 years of effort is beyond what we can reasonably do by the next release anyway, so it becomes moot. I only do this rounding after having broken down the problem, sizing the pieces, and adding it all back together. If each piece is 3 days, and there are four pieces, I don't round each one to 1 week, and come out with a month. I add it up as 12 days, which is 2.4 weeks, and round that to 3 weeks.
Good luck!