web-dev-qa-db-fra.com

Gestion des dates et des horodatages MySQL dans Java

Dans une application Java, qu'est-ce qu'un bon compromis en termes d'extraction et de saisie d'informations de date avec une base de données MySQL utilisant un mélange de dates/heures et d'horodatages?

57
James P.

Dans Java, la date est généralement représentée par le (mal conçu, mais cela mis de côté) --- Java.util.Date . Il est fondamentalement soutenu par le - Epoch time en version long, également appelée horodatage, contient des informations sur les parties date et heure. En Java, la précision est en millisecondes.

Du côté SQL, il existe plusieurs types de date et d’heure standard, DATE, TIME et TIMESTAMP (sur certains DB également appelés DATETIME), qui sont représentés dans JDBC sous la forme Java.sql.Date , Java.sql.Time et Java.sql.Timestamp , all sous-classes de Java.util.Date. La précision dépend de la base de données, souvent en millisecondes comme Java, mais peut également être en secondes.

Contrairement à Java.util.Date, Le Java.sql.Date Ne contient que des informations sur la date (année, mois, jour). Le Time ne contient que des informations sur la partie temps (heures, minutes, secondes) et le Timestamp contient des informations sur les deux parties, comme le fait Java.util.Date.

La pratique normale de stocker un horodatage dans la base de données (ainsi, Java.util.Date Dans Java et Java.sql.Timestamp Dans JDBC) est utilisé 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 pratique normale pour obtenir un horodatage à partir de la base de données consiste à utiliser ResultSet#getTimestamp() .

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

MySQL documentation contient des informations sur le mappage des types MySQL avec les types Java. En général, pour les dates et les horodatages MySQL, vous devez utiliser Java.sql.Timestamp. Quelques ressources incluent:

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

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

Comment stocker Java Date à Mysql datetime ...?

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

MODIFIER:

Comme d'autres l'ont indiqué, la suggestion d'utiliser des chaînes peut entraîner des problèmes.

8
Garett

BalusC a bien décrit le problème, mais il manque un bon code de bout en bout que les utilisateurs peuvent choisir et tester par eux-mêmes.

La meilleure pratique consiste à toujours stocker la date et l'heure dans le fuseau horaire UTC de la base de données. Le type d'horodatage SQL n'a pas d'informations de fuseau horaire.

Lors de l'écriture de la valeur datetime sur 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);

Lors de la lecture de la valeur de DB en Java,

  1. Lisez-le tel quel dans le type Java.sql.Timestamp.
  2. Décorez la valeur DateTime en heure dans le fuseau horaire UTC en utilisant la méthode atZone de la classe LocalDateTime.
  3. Ensuite, changez le fuseau horaire souhaité. Ici, je le change pour le fuseau horaire 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"));
    
4
Dorjee