Manejo de fechas y marcas de tiempo de MySQL en Java

En una aplicación java, ¿cuál sería un buen compromiso en términos de extrapolar e ingresar información de fecha con una base de datos MySQL usando una combinación de fechas y marcas de tiempo?

En el lado de Java, la fecha suele estar representada por ( java.util.Date mal diseñado, pero a un lado). Básicamente está respaldado por el tiempo de Época en el sabor de un long , también conocido como marca de tiempo. Contiene información sobre las partes de fecha y hora. En Java, la precisión está en milisegundos.

En el lado de SQL, hay varios tipos de fecha y hora estándar, DATE , TIME y TIMESTAMP (en algunos DB también llamados DATETIME ), que se representan en JDBC como java.sql.Date , java.sql.Time y java.sql.Timestamp , todas las subclases de java.util.Date . La precisión depende de la base de datos, a menudo en milisegundos, como Java, pero también puede estar en segundos.

A diferencia de java.util.Date , el java.sql.Date contiene solo información sobre la parte de la fecha (año, mes, día). El Time contiene solo información sobre la parte de tiempo (horas, minutos, segundos) y la Timestamp contiene información sobre ambas partes, como lo hace java.util.Date .

La práctica normal de almacenar una marca de tiempo en el DB (por lo tanto, java.util.Date en el lado de Java y java.sql.Timestamp en el lado de JDBC) es usar 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); 

La práctica normal para obtener una marca de tiempo de la base de datos es usar ResultSet#getTimestamp() .

 Timestamp timestamp = resultSet.getTimestamp("ts"); java.util.Date date = timestamp; // You can just upcast. 

La documentación de MySQL tiene información sobre la asignación de tipos de MySQL a tipos de Java. En general, para datetime y timestamps de MySQL debe usar java.sql.Timestamp . Algunos recursos incluyen:

http://dev.mysql.com/doc/refman/5.1/en/datetime.html

http://www.coderanch.com/t/304851/JDBC/java/Java-date-MySQL-date-conversion

Cómo almacenar la fecha de Java en Mysql datetime …?

http://www.velocityreviews.com/forums/t599436-the-best-practice-to-deal-with-datetime-in-mysql-using-jdbc.html

EDITAR:

Como otros han indicado, la sugerencia de usar cadenas puede generar problemas.

BalusC dio una buena descripción del problema, pero le falta un buen código de extremo a extremo que los usuarios puedan elegir y probar por sí mismos.

La mejor práctica es almacenar siempre la fecha y hora en la zona horaria UTC en DB. El tipo de indicación de fecha y hora Sql no tiene información de zona horaria.

Al escribir el valor de fecha y hora en 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); 

Al leer el valor de DB en Java,

  1. Léelo como está en el tipo java.sql.Timestamp.
  2. Decore el valor DateTime como tiempo en la zona horaria UTC utilizando el método atZone en la clase LocalDateTime.
  3. Luego, cámbielo a su zona horaria deseada. Aquí lo estoy cambiando a la zona horaria de Toronto.

     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"));