Time processing is a mess
The first paragraph in Teo's text is quite perceptive and believable: time processing in Java is a mess. The same goes for all the other languages and development environments that I know of. Working with a date is very complicated and complicated, especially error-prone and disappointing, because we find it intuitive. But "intuitively" does not abbreviate it when it comes to data types, databases, serialization, localization, setting in time zones and all other formalities that come with computer programming.
Unfortunately, the computer industry has largely preferred to ignore this date issue problem. Just as Unicode took too much time to be invented with an obvious need, the industry also did not know what could solve the problem of date processing.
Do not rely on Count-Since-Epoch
But I must disagree with his conclusion. Working with count-since-epoch is not the best solution. Using count-since-epoch is inherently confusing and error prone and incompatible.
We create numeric data types to do the math instead of using bits. We create string classes to handle the details of text processing, rather than bare octets. Therefore, we must create data types and classes to handle date and time values.
The early Java teams (both IBM and Taligent in front of them) made an attempt with java.util.Date and java. util.Calendar and related classes. Unfortunately, the attempt was inadequate. Although date-time is inherently confusing, these classes are even more confused.
Joda time
As far as I know, the Joda-Time project was the first project to take on a date in a thorough, and successful manner. However, the creators of Joda-Time were not completely satisfied. They continued to create the java.time package in Java 8 and extend this work with the threeten-extra project . Joda-Time and java.time use similar concepts, but differ from each other, each of which has some advantages.
Database Issues
In particular, the java.util.Date and .Calendar classes do not have values only for a date without a time and time zone. And they lack time values without a date and time zone. Before Java 8, the Java team added hacks known as java.sql.Date and java.sql.Time , which is a date-time value that masquerades as date-only. Both Joda-Time and java.time fix this by offering the LocalDate and LocalTime .
Another particular problem is that java.util.Date has a millisecond resolution, but databases often use microseconds or nanoseconds. In an ill-conceived attempt to overcome this inconsistency, the early Java team created another hack, the java.sql.Timestamp class. While technically a subclass of java.util.Date, it also tracks fractional seconds to nanosecond resolution. Therefore, when you convert and exit this type, you may lose or gain a smaller fractional second granularity without realizing this fact. Thus, this may mean that the values you expect to be equal are not.
Another source of confusion is the SQL data type, TIMESTAMP WITH TIME ZONE . This name is incorrect because time zone information is not saved. Think of the name as TIMESTAMP WITH RESPECT FOR TIME ZONE , since any transmitted time zone offset information is used to convert the date and time value to UTC .
The java.time package with its resolution in nanoseconds has some features that allow better reporting of date data with the database.
I could write a lot more, but such information can be gathered from a StackOverflow search for words like joda, java.time, sql timestamp and JDBC.
An example of using Joda-Time with JDBC with Postgres . Joda-Time uses immutable objects for thread safety , so instead of changing the instance ("mutate"), we create a new instance based on the values of the original.
String sql = "SELECT now();"; … java.sql.Timestamp now = myResultSet.getTimestamp( 1 ); DateTime dateTimeUtc = new DateTime( now , DateTimeZone.UTC ); DateTime dateTimeMontréal = dateTimeUtc.withZone( DateTimeZone.forID( "America/Montreal" ) );
Focus in UTC
Before that, I thought that timestamps were always in UTC. Why would anyone want to localize a timestamp instead of a localized representation of it? Isn't that too embarrassing for everyone?
Really. The SQL standard defines TIMESTAMP WITHOUT TIME ZONE , which ignores and removes any included time zone data. I can not imagine the usefulness of this. This Postgres expert, David E. Wheeler, says he recommends always using TIMESTAMP WITH TIME ZONE . Wheeler refers to one narrow technical exception (separation) and even then says to convert all values to UTC just before saving to the database.
The best practice is to work and store data in UTC when setting up localized time zones for presentation to the user. There may be times when you want to remember the original date and time in a localized time zone; if so, save this value in addition to converting to UTC.
Guide
The first steps to improve processing in date mode is to avoid java.util.Date and .Calendar using Joda-Time and / or java.time, focusing on UTC and studying the behavior of your specific JDBC driver and your specific databases (the databases are very different regarding data processing, despite the SQL standard).