There are unfortunately lots of things wrong with the old java.util.Date and java.util.Calendar classes. To name a few things:
Class Date has the wrong name. Despite the name, it does not represent a date (indicating a specific day of a specific month in a specific year). Instead, it is really a timestamp (internally it stores a number of milliseconds since 01-01-1970, 00:00:00 GMT). It is not very well suited for storing just a date (day, month, year), or just a time of day (hours, minutes, seconds, milliseconds), but people try to use it that way anyway.
There is a lot of misunderstanding about the classes Date and Calendar. People ask questions like "I want to have a Date object in the format yyyy-MM-dd" or "I want to convert my Date object from one timezone to another". Date objects do not have a format and do not know anything about timezones, so you cannot have a Date object with a certain format or in a certain timezone. I've seen a lot of
cargo cult code, sometimes written by experienced Java developers, trying to do strange things with Date objects because the programmer misunderstood what a Date object is exactly.
Classes Date and Calendar make no distinction between "absolute" points in time and date and time values that do not indicate an "absolute" point in time. Joda Time specifically does make this distinction. Anything that is an Instant in Joda Time represents an "absolute" moment in time. A class such as LocalDateTime is not an "absolute" moment in time - for example, what 01-05-2015 09:22:00 means exactly depends on the timezone you're in. This distinction is often important in software, and Java's old date and time API makes it hard.
Classes Date and Calendar are not
immutable and not thread-safe. They should have been designed as
value objects and should have been immutable. Also, SimpleDateFormat is not thread-safe - it's not safe to make a
public static final SimpleDateFormat variable in a multi-threaded program; if multiple threads try to use it at the same time, you'll get strange results.
Months are numbered starting at 0 in class Calendar, making it very easy to make mistakes:
cal.set(2015, 5, 1); sets the calendar to 1
June 2015 instead of 1 May 2015 because 0 = January, 1 = February, ..., 4 = May, 5 = June, ...
Class Calendar has a method named
getTime() that returns a Date object. An absolutely unintuitive method name.
The old Java date and time API has (almost) no support for working with durations and periods, or alternative chronologies (for example, the Buddhist or Arabic calendar systems).
Joda Time has a much better designed API for working with date and time. It's too bad it took so long before Java got a decent date and time API.