The times when I've been involved in projects which accurately stated release dates, we have done it by dividing features into "essential for this release" and "can be slipped to next release", then choosing a release date such that we're very comfortable we can complete all essential features, and think there is at least some chance of completing all inessential features.
Of course this rather raises the question of why we're even considering the inessential features, but in a practical project there are usually several things which can be moved in one direction or the other, according to (a) whether the customer gets wind of the proposed feature and if so whether they like it, (b) how soon the following release is expected to be and how easy it is for the customer to upgrade then, (c) how your business plan is affected by, respectively, a saleable product now, or the Ultimate Product of Awesomeness next year.
So what actually happens is three categories, "essential and expected to remain essential: if this is not done on time we will be forced to release late", "treated as essential for now, but we may change our minds as the release date approaches", and "treated as not for this release for now, but we will pull it forward if time permits".
A lot of the projects I've been involved with, though, have been very long running, and interim releases are basically snapshots of the current working version. It feels like cheating to say you "gave an accurate a release date", when what actually happened is that a customer asked for an update, you checked your active bug list for that customer and saw that you had two outstanding issues that affected them, figured it'd take a week to fix both and do verification, and told them "we'll give you a drop in 1-2 weeks".