In a java application what would a good compromise in terms of extracing and inputting date information with a MySQL database using a mix of datetimes and timestamps?
3 Answers
In Java side, the date is usually represented by the (poorly designed, but that aside) java.util.Date
. It is basically backed by the Epoch time in flavor of a long
, also known as a timestamp. It contains information about both the date and time parts. In Java, the precision is in milliseconds.
In SQL side, there are several standard date and time types, DATE
, TIME
and TIMESTAMP
(at some DB's also called DATETIME
), which are represented in JDBC as java.sql.Date
, java.sql.Time
and java.sql.Timestamp
, all subclasses of java.util.Date
. The precision is DB dependent, often in milliseconds like Java, but it can also be in seconds.
In contrary to java.util.Date
, the java.sql.Date
contains only information about the date part (year, month, day). The Time
contains only information about the time part (hours, minutes, seconds) and the Timestamp
contains information about the both parts, like as java.util.Date
does.
The normal practice to store a timestamp in the DB (thus, java.util.Date
in Java side and java.sql.Timestamp
in JDBC side) is to use PreparedStatement#setTimestamp()
.
java.util.Date date = getItSomehow();
Timestamp timestamp = new Timestamp(date.getTime());
preparedStatement = connection.prepareStatement("SELECT * FROM tbl WHERE ts > ?");
preparedStatement.setTimestamp(1, timestamp);
The normal practice to obtain a timestamp from the DB is to use ResultSet#getTimestamp()
.
Timestamp timestamp = resultSet.getTimestamp("ts");
java.util.Date date = timestamp; // You can just upcast.

- 1,082,665
- 372
- 3,610
- 3,555
-
6do you think that using java.sql.Timestamp in the model (Java layer) is bad? – cherouvim Jul 24 '10 at 05:20
-
10@cherouvim: Yes. The model shouldn't be aware of any JDBC specifics. Only use it to set the timestamp. `preparedStatement.setTimestamp(new Timestamp(date.getTime()));`. Getting it is easy since it's already a subclass of `java.util.Date`. – BalusC Jul 24 '10 at 05:30
-
3This will work fine if all your machines and users are in the same timezone. Otherwise, beware the MySQL JDBC driver's handling of timezone conversions is incredibly complex and buggy. For example see http://stackoverflow.com/questions/40670532/what-are-jdbc-mysql-driver-settings-for-sane-handling-of-datetime-and-timestamp/40681941#40681941 – Alex R Nov 20 '16 at 18:02
-
BalusC, what type should I use then for a column inside DB in your opinion (Date/Timestamp?). Following your example I receive something like 2017-01-24 19:17:11.0 when I read from DB, but before it was Tue Jan 24 19:17:11 EET 2017. Moreover, when I compare using compareTo, I get: before > after. P.S. I use timestamp in DB – Sabine Jan 24 '17 at 17:35
-
@Sabine: You have a timestamp with timezone. This is not supported by all DBs. E.g. PostgreSQL and Oracle do, but MySQL not. You'd need to convert to a fixed timezone before saving in DB. Usually UTC is used. – BalusC Jan 24 '17 at 21:18
The MySQL documentation has information on mapping MySQL types to Java types. In general, for MySQL datetime and timestamps you should use java.sql.Timestamp
. A few resources include:
http://dev.mysql.com/doc/refman/5.1/en/datetime.html
http://www.coderanch.com/t/304851/JDBC/java/Java-date-MySQL-date-conversion
How to store Java Date to Mysql datetime...?
EDIT:
As others have indicated, the suggestion of using strings may lead to issues.
-
-
6Don't massage it forth and back as string. It's recipe for portability and maintainability trouble. – BalusC Jul 24 '10 at 04:57
-
BalusC gave a good description about the problem but it lacks a good end to end code that users can pick and test it for themselves.
Best practice is to always store date-time in UTC timezone in DB. Sql timestamp type does not have timezone info.
When writing datetime value to sql db
//Convert the time into UTC and build Timestamp object.
Timestamp ts = Timestamp.valueOf(LocalDateTime.now(ZoneId.of("UTC")));
//use setTimestamp on preparedstatement
preparedStatement.setTimestamp(1, ts);
When reading the value back from DB into java,
- Read it as it is in java.sql.Timestamp type.
- Decorate the DateTime value as time in UTC timezone using atZone method in LocalDateTime class.
Then, change it to your desired timezone. Here I am changing it to Toronto timezone.
ResultSet resultSet = preparedStatement.executeQuery(); resultSet.next(); Timestamp timestamp = resultSet.getTimestamp(1); ZonedDateTime timeInUTC = timestamp.toLocalDateTime().atZone(ZoneId.of("UTC")); LocalDateTime timeInToronto = LocalDateTime.ofInstant(timeInUTC.toInstant(), ZoneId.of("America/Toronto"));

- 1,533
- 1
- 12
- 9