Other answers use obsolete classes.
java.time
Both Joda-Time and the old java.util.Date/.Calendar classes were supplanted using the java.time framework built into Java 8 and later. Defined by JSR 310 . Extended in the ThreeTen-Extra project. Back-ported in Java 6 and 7 using the ThreeTen-BackPort project , which is completed for Android using the ThreeTenABP project.
LocalDate
A date value only with no time and no time zone can be represented by the LocalDate class. Such a class was not present in older time classes associated with earlier versions of Java. The old java.sql.Date class pretends to be date-only, but actually has a time inherited from java.util.Date (date value).
LocalDate dateOfBirth = LocalDate.new( 1979 , 1 , 10 );
Without the time of day and time zone, the date of birth is inherently inaccurate for determining age. But in almost all precedents, we do not care. give or take part in the day close enough.
ZonedDateTime
For a meeting, we cannot be so licentious. We need a date, time and time zone. In java.time, this means the ZonedDateTime class. The time zone is a key element that is not in the script in the Question. Add a time zone and everything will be fine.
ZoneId zoneIdMontreal = ZoneId.of( "America/Montreal" ); ZonedDateTime zdtMontreal = ZonedDateTime.of( 2010 , 1 , 10 , 20 , 0 , 0 , zoneIdMontreal );
Now transfer the objects to another computer. Both remain untouched, the same date value only for the date of birth (1979-01-10) and the same time for meeting in Montreal.
Time Zone Setting
You can then set up this appointment in a different time zone expected by the person using this other machine.
ZoneId zoneIdParis = ZoneId.of( "Europe/Paris" ); ZonedDateTime zdtParis = zdtMontreal.withZone( zoneIdParis );
We have the same moment on the timeline, presented in two models, in two objects: zdtMontreal and zdtParis.
LocalDateTime
If your nextMeeting does not have a time zone or offset information from UTC, then think of it as a LocalDateTime object. It will be stored in the database as a type of type TIMESTAMP WITHOUT TIME ZONE .
Such values ββdo not represent a point in time. They represent only a number of possible points. To determine the actual moment, you must specify the context of a specific time zone.
To store future date values, such as a scheduled meeting, after more than a few weeks, doing this without a time zone may be appropriate. Politicians around the world have shown a tendency to change summer time frequently and, otherwise, redefine their time zones. And they often do this with a little warning, in just a few weeks of warning.
To determine the actual moment, for example, showing the schedule on the calendar, use the ZoneId time zone to get the ZonedDateTime .
ISO 8601
The java.time classes use standard ISO 8601 formats by default when parsing / generating text representations of date and time values. The ZonedDateTime class goes one step further, extending ISO 8601 to add the time zone name in square brackets.
If you serialize values ββby text, use ISO 8601 for reasonable and unambiguous formats.
None of the issues raised in the Question remain. Using an excellent time library and ISO 8601, such as java.time, solves the problem.
Database
Your database should use the date type only for the date of birth and the time type with the timeline for the collection (see SQL Data Types on Wikipedia and in your database documentation). Your JDBC driver alerts you to both types.
In the end, JDBC drivers will be updated to use java.time types directly. But before that, we need to convert java.sql types such as java.sql.Date and java.sql.Timestamp . New methods have been added to old classes to support these transformations.
java.sql.Date sqlDateOfBirth = java.sql.Date.valueOf( dateOfBirth ); java.sql.Timestamp sqlMeeting = java.sql.Timestamp.valueOf( zdtMontreal );
Then call setDate and setTimestamp on the PreparedStatement .
In the other direction, from database to Java, call getDate and getTimestamp on a ResultSet . Then translate immediately to java.time types, avoiding the use of java.sql types in your business logic.
For the date and time value, we must go through the Instant object. Instant is the moment on the timeline in UTC . We use the time zone to get the wall clock for the user.
LocalDate dateOfBirth = mySqlDate.toLocalDate(); Instant instant = mySqlTimestamp.toInstant(); ZonedDateTime zdtMontreal = ZonedDateTime.ofInstant( instant , zoneIdMontreal );