We, as programmers, are constantly being asked 'How long will it take'?

And you know, the situation is almost always like this:


The requirements are unclear. Nobody has done an in depth analysis of all the implications.
The new feature will probably break some assumptions you made in your code and you start thinking immediately of all the things you might have to refactor. 
You have other things to do from past assignments and you will have to come up with an estimate that takes that other work into account.
The 'done' definition is probably unclear: When will it be done? 'Done' as in just finished coding it, or 'done' as in "the users are using it"?
No matter how conscious you are of all these things, sometimes your "programmer's pride" makes you give/accept shorter times than you originally suppose it might take. Specially when you feel the pressure of deadlines and management expectations.


Many of these are organizational or cultural issues that are not simple and easy to solve, but in the end the reality is that you are being asked for an estimate and they expect you to give a reasonable answer. It's part of your job. You cannot simply say: I don't know. 

As a result, I always end up giving estimates that I later realize I cannot fulfill. It has happened countless of times, and I always promise it won't happen again. But it does.

What is your personal process for deciding and delivering an estimate? What techniques have you found useful?

From The Pragmatic Programmer: From Journeyman to Master:


  What to Say When Asked for an Estimate
  
  You say "I'll get back to you."
  
  You almost always get better results if you slow the process down and spend some time going through the steps we describe in this section. Estimates given at the coffee machine will (like the coffee) come back to haunt you.


In the section, the authors recommend the following process:


Determine the accuracy that you need. Based on the duration, you can quote the estimate in different precision. Saying "5 to 6 months" is different than saying "150 days". If you slip a little into the 7th month, you're still pretty accurate. But if you slip into the 180th or 210th day, not so much.
Make sure you understand what is being asked. Determine the scope of the problem.
Model the system. A model might be a mental model, diagrams, or existing data records. Decompose this model and build estimates from the components. Assign values and error ranges (+/-) to each value.
Calculate the estimate based on your model.
Track your estimates. Record information about the problem you are estimating, your estimate, and the actual values.
Other things to include in your estimate are developing and documenting requirements or changes to requirements specifications, creating or updating design documents and specifications, testing (unit, integration, and acceptance), creating or updating user's manuals or READMEs with the changes. If 2 or more people working together, there's overhead of communication (phone calls, emails, meetings) and merging source code. If it's a long task, account for things like other work, time off (holidays, vacation, sick time), meetings, and other overhead tasks when picking a delivery date.

