IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JDBC Java Discussion :

Enregistrement d'un timestamp en BDD


Sujet :

JDBC Java

  1. #1
    Invité
    Invité(e)
    Par défaut Enregistrement d'un timestamp en BDD
    Bonjour,

    Je cherche à enregistrer un timestamp avec timezone dans ma base de données SQL (postgresql).

    Du coté java, j'utilise un java.util.Date. Du coté postgresql, j'utilise un TIMESTAMP WITH TIMEZONE.

    Or à chaque fois que j'enregistre une date, c'est la date locale qui est enregistrée en tant que GMT. Exemple :
    - Il est 23h37 (ca fais donc 3h que je planche la dessus ^) heure locale
    - Quand j'enregistre la date (avec un PreparedStatement et un setTimeStamp), celle-ci apparait dans la base comme "31/05/2014 23:37 GMT" alors qu'elle devrait être à "31/05/2014 21:37 GMT".

    J'ai essayé d'ajouter un Calendar avec setTimestamp, mais ça ne change rien. J'ai essayé de convertir la date en GMT avant enregistrement mais n'y suis pas arrivé.
    Ce que je ne comprend pas, c'est que le Date reflete le nombre de ms depuis le 01/01/1970 GMT. Donc l'enregistrement en base de cette valeur devrait refleter la même chose.
    J'ai chercher dans le forum, j'ai trouvé pas mal de sujet sur l'affichage, mais rien qui puisse m'aider sur l'enregistrement.

    Sauriez-vous m'aider sur ce sujet ?

    Merci,

    un extrait du code que j'utilise (j'ai essayé plein d'autres solutions auparavant, sans succès) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    PreparedStatement req = _cnx.prepareStatement(statement_text);
    java.util.Calendar cal = java.util.Calendar.getInstance(java.util.TimeZone.getTimeZone("Europe/Paris"),new java.util.Locale("fr","fr"));
    cal.setTime(new java.util.Date());
    java.util.Date datedujour = new Date();
    (...)
    req.setTimestamp(9, new java.sql.Timestamp(datedujour.getTime()));

  2. #2
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2012
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2012
    Messages : 51
    Points : 55
    Points
    55
    Par défaut
    Tiens je pense que ceci pourrais t'aider :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     Date date = new Date();
            Timestamp timeStampDate = new Timestamp(date.getTime());
    Utilise ce code pour récupérer un timestamp

    et celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    preparedstatement.setObject(2,timeStampDate, Types.TIMESTAMP);
    avec une requête préparé pour insérer ton timestamp dans la colonne correspondante

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par GrosShrek Voir le message

    J'ai essayé d'ajouter un Calendar avec setTimestamp, mais ça ne change rien.
    Quand je lit ton code, ce n'est pas un Calendar que tu utilise, mais une long, qui proviens d'un java.util.Date, qui proviens d'un Calendar. Sur le paquet, seul Calendar a une notion de timezone, donc tu dois bien te dire que ca n'ira pas jusque la base de données

    Etonnament, il y a des méthodes setTimestamp qui prennent un Calendar en paramètres, et qui pourraient servir à ça....


    Aussi, quelle raison fait que tu as besoin dans ta base de données d'un Timestamp avec timezone. Il est très rare d'avoir besoin de différencer


    jeudi 3/6/2014 18.00 Europe/Brussel de jeudi 3/6/2014 17.00 UTC, puisqu'il s'agit du même instant dans la vie de l'univers.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Au vu des vos réponses, je penses que je me suis pas mal embrouillé. Je vais donc vous expliquer mon besoin de départ.
    Je souhaite créer une application qui puisse etre utilisé par des personnes vivant sur des fuseaux horaires différents, et qu'elles puissent travailler sur les mêmes événement mais avec leur propre fuseau. Par exemple :
    J'ai un utilisateur Gérard qui vis à Paris (GMT+2)
    un autre utilisateur James vivant à New York (GMT-4)

    Gérard crée un événement X à 20h heure locale, soit 14h heure New York.

    A l'affichage, James doit donc voir afficher 14h00.

    Mais aussi si James recherche les événements débutant à 14h00, il doit retrouver l'événement X.
    Si il cherche les événements débutant à 20h00 il ne trouve rien.

    De même pour Gérard, s'il recherche un événement débutant à 20h00, il doit retrouver X.

    Quels outils/classes/requêtes puis-je utiliser pour résoudre cela ?

    J'ai actuellement trouvé une solution mais elle ne me plait pas car elle utilise des conversion en chaines. Je trouve cela dommage, j'imagine qu'il doit y avoir un solution plus simple avec les timestamp, car étant universel, ils devraient répondre à mon besoin.

    Ma solution actuelle :
    Colonne en BDD au format TIMEZONE WITH TUMESTAMP
    - J'enregistre ma donnée avec un timestamp (j'ai l'impression que setTimestamp fournis en fait une date au format chaine avec le fuseau)
    - Je fais ma recherche (SELECT) en passant une chaine en paramètre (setString) représentant la date avec le fuseau du client (obtenue avec un SimpleDateFormat).

    Si vous connaissez une méthode plus propre, qui ne nécessite pas de conversion en chaine, je suis preneur.

    Au passage, je réalise une application web en JSP.

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Tu n'as pas besoin de timezone dans ta base de données pour ton besoin, une simple timestamp suffit. En effet, tu n'a pas besoin, dans la base de données, de savoir, en plus du moment de l'évènement, dans quelle timezone il a été créé. Pour la base de données, et pour les programmes, 7/6/2014 10h00 GMT et 7/6/2014 14h00 GMT+4, c'est exactement la même valeur qui est stockée sous forme binaire, c'est le nombre de millisecondes écoulées depuis le 1er janvier 1970 00:00 GMT. Et quel que soit mon fuseau, ce nombre est identique

    Là où les fuseau commence à servir, c'est quand on convertit ce nombre depuis et vers des interfaces graphiques, des ficheirs textes, etc. Bref, quand on change ce long en quelque chose de plus parlant pour un utilisateur.

    Pour ton insertion dans la base de données, tu utilise la méthode setTimestamp() de preparedStatement
    Pour ta lecture de la base de données, tu utilise la méthode getTimestamp()
    Pour ta recherche, pareil, setTimestamp() sur le paramètres en question.


    Pour ton code, cette logique devrait être entreprise:

    Entrée d'une date / heure dans la calendrier local (7/6/2014 14h00) => Ajout de la timezone de l'utilisateur (GMT+4) et construction d'un DateFormatter avec tout ça => Utilisation de ce texte + ce formatter pour constuire un java.util.Date (on a maintenant un moment dans le temps) => Processus d'insertion dans la DB de cette date.

    Puis à la lecture

    Récupération du timestamp en base de données (7/6/2014 10h00 GMT) => Construction d'un formatter avec la timezone (GMT+2) de l'utilisateur => Transformation du timestamp en String en utilisant ce formatter et affichage.


    Si tu dois faire, par la suite, des calendrier visuels, de la décompositions des champs de la date -> Remplace le formatter par un java.util.Calendar et utilise ses méthodes setDate / get(Calendar.MONTH), etc...


    Voilà dans les grandes lignes. Tu ne dois gérer te timezone qu'au moment de l'affichage en gros. La données brut (le long représentant la date) et agnostique à la timezone. Pour penser plus simplement, dit toi qu'un java.util.Date et représenté en interne par rapport à GMT et que tout les méthodes qui font Date <=> Texte ou Date <=> décomposition passent par cette timezone commune pour que tout le monde parle la même donnée

  6. #6
    Invité
    Invité(e)
    Par défaut
    Merci pour vos réponses. J'ai finis par trouver comment faire grâce à vos conseils.

    Voici un exemple de code pour UN SELECT :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    			Calendar first = Calendar.getInstance();
    			first.setTimeZone(TimeZone.getTimeZone("GMT+0"));
    			first.set(2014, Calendar.JUNE , 17, 19, 00);
     
    			// insertion
    			String statement_text = "SELECT * "
    								+ "FROM table"
    								+ " WHERE mydate >= ?";
     
    			PreparedStatement req = cnx.prepareStatement(statement_text);
    			req.setTimestamp(1, new java.sql.Timestamp(first.getTimeInMillis()));
    			ResultSet rs = req.executeQuery();
    Le code est fonctionnel, prend en charge les fuseau et utilise bien les timestamp, donc parfait

    Merci beaucoup,

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Enregistrer un champ de type timestamp en BDD
    Par ZenZiTone dans le forum Langage
    Réponses: 3
    Dernier message: 07/02/2014, 16h38
  2. enregistrer un chemin dans une BDD MySQL
    Par Sargon dans le forum C#
    Réponses: 11
    Dernier message: 23/08/2007, 11h59
  3. Pb lors de l'enregistrement des sessions dans une BDD
    Par tomcoch dans le forum Langage
    Réponses: 2
    Dernier message: 17/04/2007, 10h14
  4. probleme d'enregistrement des accents dans la BDD
    Par Gloup dans le forum Installation
    Réponses: 1
    Dernier message: 09/07/2006, 21h07
  5. [SGBD] FPDF+enregistrer le pdf généré dans BDD MySQL
    Par Flushovsky dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 29/11/2005, 16h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo