A big part of the problem is that management often isn't interested in honest estimates.
You can certainly find better practices in some organizations, but in many organizations, a certain team gets tasked with completing a certain assignment by an arbitrary deadline and no attempt is made to reconcile the triple constraints with reality.
In a context like that, developers may not be asked to make estimates, and if they do make estimates they don't believe that they'll be taken seriously. So they never develop the chance to learn how to estimate.
The accuracy of estimation also depends on the context.
If, for some reason, I had to fix a difficult-to-reproduce bug in a large system written in COBOL that runs on a mainframe, I'd have very little idea of how long it would take me to learn COBOL, understand the codebase, figure out the tools, and track the problem down. A COBOL jock would obviously do better.
On the other hand, I've worked on greenfield well-specified business CRUD apps based on a correctly aligned framework where I could estimate that something would take 21.25 hours and I'd really get it done in 19.75 or 22.50.
I've met developers who will absolutely refuse to estimate anything but I think more often developers don't believe their estimates will be listened to.
The good news for both developers and managers is that estimation is a learnable skill. If you get in the habit of making estimates and testing them, you'll get better amazingly fast. See the classic book
http://www.amazon.com/Software-Estimation-Demystifying-Pract...