Gestion des datetimes et des horodateurs MySQL en Java

dans une application java, quel serait un bon compromis en termes d'extraction et de saisie des informations de date avec une base de données MySQL utilisant un mélange de datetimes et de timestamps?

51
demandé sur BalusC 2010-07-24 06:53:54

3 réponses

côté Java, la date est généralement représentée par le (mal conçu, mais que) java.util.Date . Il est essentiellement soutenu par le époque temps dans la saveur d'un long , également connu comme un timestamp. Il contient aussi des informations sur la date et l'heure de pièces. En Java, la précision est en millisecondes.

côté SQL, il y a plusieurs types de date et d'heure standard, DATE , TIME et TIMESTAMP (à certains DB aussi appelé DATETIME ), qui sont représentés dans JDBC comme java.sql.Date , java.sql.Time et java.sql.Timestamp , toutes les sous-classes de java.util.Date . La précision est dépendante de DB, souvent en millisecondes comme Java, mais elle peut aussi être en secondes.

contrairement à java.util.Date , le java.sql.Date contient uniquement des informations sur la date partie (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 java.util.Date .

la pratique normale pour stocker un timestamp dans le DB (donc, java.util.Date côté Java et java.sql.Timestamp côté JDBC) est d'utiliser 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 de la DB est d'utiliser ResultSet#getTimestamp() .

Timestamp timestamp = resultSet.getTimestamp("ts");
java.util.Date date = timestamp; // You can just upcast.
97
répondu BalusC 2010-07-24 04:53:29

MySQL documentation a des informations sur la cartographie de MySQL types de types Java. En général, pour MySQL datetime et timestamps vous devez utiliser java.sql.Timestamp . Quelques ressources comprennent:

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 sauvegarder la date Java dans Mysql datetime...?

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

EDIT:

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

8
répondu Garett 2017-05-23 12:02:44

BalusC a donné une bonne description du problème, mais il manque un bon code de bout en bout que les utilisateurs peuvent choisir et tester pour eux-mêmes.

la meilleure pratique est de toujours stocker la date-heure dans le fuseau horaire UTC en DB. Le type de timestamp Sql n'a pas d'informations sur le fuseau horaire.

lors de l'écriture de la valeur datetime à 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 retour de DB en java,

  1. Lire il est en java.SQL.Timestamp type.
  2. décorer la valeur de DateTime en temps dans le fuseau horaire UTC en utilisant atZone méthode en classe LocalDateTime.
  3. alors, changez-le à votre fuseau horaire désiré. Ici je le change en 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"));
    
3
répondu Dorjee 2018-04-24 14:56:28