Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    [Java] Data diminuita di un giorno su db MySql

    Ciao a tutti,
    sto realizzando una semplice web application che permette di inserire tramite form di una pagina jsp, dei dati relativi ad una persona(nome, cognome e data di nascita) su db MySql.
    L'applicativo sembra funzionare correttamente tranne per il fatto che, inserendo una data nella casella del form relativa alla data di nascita(es. 25/03/1988) controllando sul db MySql, tale data risulta essere 1988-03-24, ovvero diminuita di un giorno.
    Premetto che la colonna relativa alla data di nascita su MySql, è in formato date e non datetime​.
    Ho praticamente girato tutto il web in cerca della soluzione al problema, cercando pure su stack overflow, ma senza risultati.
    Di seguito il codice dell'applicativo, nella speranza che qualcuno di voi possa darmi una mano:

    Il bean

    codice:
        package bean;
    
    import java.io.Serializable;
    import java.sql.Date;
    
    
    public class Persona implements Serializable {
        
        private int idPersona;
        private String nome;
        private String cognome;
        private Date dataNascita;
        
        public Persona() {
            super();
    
    
        }
    
    
        public Persona(String nome, String cognome, Date dataNascita) {
            super();
            this.nome = nome;
            this.cognome = cognome;
            this.dataNascita = dataNascita;
        }
    
    
        public Persona(int idPersona, String nome, String cognome, Date dataNascita) {
            super();
            this.idPersona = idPersona;
            this.nome = nome;
            this.cognome = cognome;
            this.dataNascita = dataNascita;
        }
    
    
        public int getIdPersona() {
            return idPersona;
        }
    
    
        public void setIdPersona(int idPersona) {
            this.idPersona = idPersona;
        }
    
    
        public String getNome() {
            return nome;
        }
    
    
        public void setNome(String nome) {
            this.nome = nome;
        }
    
    
        public String getCognome() {
            return cognome;
        }
    
    
        public void setCognome(String cognome) {
            this.cognome = cognome;
        }
    
    
        public Date getDataNascita() {
            return dataNascita;
        }
    
    
        public void setDataNascita(Date dataNascita) {
            this.dataNascita = dataNascita;
        }
    
    
    }
    La servlet

    codice:
        package servlet;
    
    import java.io.IOException;
    import java.sql.Date;
    import java.sql.SQLException;
    import java.text.ParseException;
    
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    
    import bean.Persona;
    import dao.ProvaDao;
    import utility.ManipolazioneDate;
    
    
    /**
     * Servlet implementation class Inserimento
     */
    @WebServlet("/Inserimento")
    public class Inserimento extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
    
        /**
         * Default constructor. 
         */
        public Inserimento() {
          
            
        }
    
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
            String nome = request.getParameter("nome");
            String cognome = request.getParameter("cognome");
            String dataNascita = request.getParameter("dataNascita");
            Date dataN = null;
            try {
                dataN = (Date) ManipolazioneDate.convertiData(dataNascita);
            } catch (ParseException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            
            Persona p = new Persona(nome, cognome, dataN);
            System.out.println(p.getNome());
            System.out.println(p.getCognome());
            System.out.println(p.getDataNascita());
            
            try{
                ProvaDao.registraPersona(p);
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
    
    
    }
    Una classe con un metodo per convertire la data in formato String, proveniente dal form, in una java.sql.Date

    codice:
        package utility;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    
    public class ManipolazioneDate {
        
        public static Date convertiData(String data) throws ParseException{
            
            SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
            Date parser = format.parse(data);
            java.sql.Date dataSql = new java.sql.Date(parser.getTime());
            
            return dataSql;
            
        }
    
    
    }
    La jsp con la form per l'inserimento dati
    codice:
        <%@ page language="java" contentType="text/html; charset=ISO-8859-1"    pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    	<div align="center">
    		<form action="/Prova/Inserimento" method="get">
    			<p>Nome</p>
    			<input type="text" value="" name="nome">
    			<br>
    			<p>Cognome</p>
    			<input type="text" value"" name="cognome">
    			<br>
    			<p>Data di nascita</p>
    			<input type="text" value="" name="dataNascita">
    			<br>
    			<input type="submit" value="Invia">
    			
    		</form>
    	</div>
    </body>
    </html>
    Il dao con il metodo per l'nserimento dei dati nel db

    codice:
        package dao;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    
    import bean.Persona;
    import utility.Connessione;
    
    
    public class ProvaDao {
        
        public static void registraPersona(Persona persona) throws SQLException{
            
            Connection conn = Connessione.getConnection();
            PreparedStatement ps = null;
    
    
            
            String ins = "insert into prova2.persona(nome, cognome, dataNascita) values(?,?,?)";
            
            try{
                
                ps = conn.prepareStatement(ins);
                
                ps.setString(1, persona.getNome());
                ps.setString(2, persona.getCognome());
                ps.setDate(3, persona.getDataNascita());
                
                ps.executeUpdate();
                System.out.println("Persona inserita");
                
            }catch(SQLException e){
                
                System.out.println(e.getMessage());
                System.out.println("Errore nell'inserimento");
                
            }finally{
                
                if(ps != null){
                    ps.close();
                }
                
                if(conn != null){
                    conn.close();
                }
            }
        }
    
    
    }

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,082
    Ad occhio non vedo problematiche in tal senso.
    Potresti postare anche la classe Connessione (ovviamente, rimuovendo i riferimenti all'utente / password)? Perchè ho come il sentore che la cosa dipenda dal nuovo Connector/J, che richiede per la connessione anche il parametro relativo al TimeZone.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Ad occhio non vedo problematiche in tal senso.
    Potresti postare anche la classe Connessione (ovviamente, rimuovendo i riferimenti all'utente / password)? Perchè ho come il sentore che la cosa dipenda dal nuovo Connector/J, che richiede per la connessione anche il parametro relativo al TimeZone.


    Ciao.
    Eccola:

    codice:
       package utility;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    
    public class Connessione {
    
    
    public static Connection getConnection(){
            
            Connection conn = null;
            
            try{
                
                Class.forName("com.mysql.jdbc.Driver");
                
            }catch(ClassNotFoundException e){
                
                System.out.println("Non riesco a trovare i Driver JDBC di MySQL");
                e.printStackTrace();
                return conn;
            }
            System.out.println("Driver JDBC di MySQL registrati");
            
            try{
                
                conn = DriverManager.getConnection("jdbc:mysql://localhost/prova2?user=&password=&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC");
                
            }catch(SQLException e){
                System.out.println("Connessione fallita");
                e.printStackTrace();
                return conn;        
            }
            
            if(conn != null){
                
                System.out.println("Sei connesso al database");
                
            }else{
                
                System.out.println("Connessione al db non riuscita");
            }
            
            return conn;
            
        }
    }

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,082
    Infatti, credo che il problema sia la differenza tra il TimeZone utilizzato dalla tua JVM (che sarà quello di sistema, quindi immagino tarato sul TimeZone dell'Italia) e quello che tu hai specificato per il server (UTC, ovvero il TimeZone utilizzato dai paesi nel meridiano di Greenwich, che rispetto a noi sono sempre 1/2 ore indietro in base all'ora legale/solare).

    Documentandomi in giro, dovresti poter risolvere usando il setDate() di PreparedStatement da tre parametri, in questo modo:

    codice:
    ps.setDate(3, persona.getDataNascita(), Calendar.getInstance());

    Questo dovrebbe fornire al server il TimeZone in cui è espressa la data passata come argomento... costruendo, quindi, un oggetto Calendar in quel modo, viene di fatto istanziato un oggetto con il TimeZone di default della JVM su cui gira l'applicazione (che, appunto, dovrebbe essere quello dell'Italia). Attenzione, però, in lettura dei dati (non ho modo di provare ora), perchè potresti leggerli "sfasati".

    Prova e fammi sapere.


    Spiego quello che succede: nella connection string hai specificato useLegacyDatetimeCode=false e serverTimeZone=UTC. La combinazione di questi due fa sì che i metodi che trattano dati temporali (date / time / datetime / timestamp / ecc) vengano "normalizzati" dal driver JDBC quando vengono spediti al server (o letti dal server). Quindi, tu hai la tua JVM che funziona con TimeZone locale dell'Italia (ora siamo a UTC+1) e hai istruito il driver JDBC affinchè non utilizzi i dati temporali in modo legacy (quindi deve applicare le normalizzazioni) e gli hai detto che il server è in TimeZone UTC. Il driver, quando riceve la richiesta di memorizzare sul server MySQL un dato temporale lo allinea al TimeZone del server (quindi, nel tuo caso, toglie 1 ora) e glielo passa. Se invece riceve una richiesta di lettura di un dato temporale, effettua l'operazione opposta: sa che sta leggendo da un server che memorizza i dati in UTC e li trasla al TimeZone della JVM che li sta richiedendo (quindi, nel tuo caso, aggiunge 1 ora al dato di MySQL). In questo modo, tu scrivi e leggi sempre il dato corretto (se lo fai tramite Java)... ma se vai in console su MySQL ti trovi il dato sfasato.

    PS: faccio notare che se il server gira sulla tua macchina (o, comunque, è qui in Italia) sei tu che stai dando al driver JDBC un'informazione falsa dicendogli che il server lavora in UTC...

    Ciao.
    Ultima modifica di LeleFT; 11-03-2019 a 18:13
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Infatti, credo che il problema sia la differenza tra il TimeZone utilizzato dalla tua JVM (che sarà quello di sistema, quindi immagino tarato sul TimeZone dell'Italia) e quello che tu hai specificato per il server (UTC, ovvero il TimeZone utilizzato dai paesi nel meridiano di Greenwich, che rispetto a noi sono sempre 1/2 ore indietro in base all'ora legale/solare).

    Documentandomi in giro, dovresti poter risolvere usando il setDate() di PreparedStatement da tre parametri, in questo modo:

    codice:
    ps.setDate(3, persona.getDataNascita(), Calendar.getInstance());

    Prova e fammi sapere.
    Funziona alla grande!! Grazie mille! Non sai quanto ho cercato in giro per risolvere questo cavolo di problema!
    Già che sei stato così gentile vorrei porti un'altra domanda(ovviamente se hai voglia e tempo di rispondere):
    Il codice del form che ho postato è semplificato.
    Nell'applicativo originale la casella di testo per l'immissione delle date era una casella di tipo datedi bootstrap che ovviamente ho dovuto sostituire con una casella di tipo text, in quanto la precedente mi dava errore nella conversione della data. La cosa mi sembra alquanto strana poiché il tipo di dato che esce da una casella di tipo date è una stringa.
    Sai per caso a cosa è dovuto questo problema?

  6. #6
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Infatti, credo che il problema sia la differenza tra il TimeZone utilizzato dalla tua JVM (che sarà quello di sistema, quindi immagino tarato sul TimeZone dell'Italia) e quello che tu hai specificato per il server (UTC, ovvero il TimeZone utilizzato dai paesi nel meridiano di Greenwich, che rispetto a noi sono sempre 1/2 ore indietro in base all'ora legale/solare).

    Documentandomi in giro, dovresti poter risolvere usando il setDate() di PreparedStatement da tre parametri, in questo modo:

    codice:
    ps.setDate(3, persona.getDataNascita(), Calendar.getInstance());

    Prova e fammi sapere.
    Funziona alla grande!! Grazie mille! Non sai quanto ho cercato in giro per risolvere questo cavolo di problema!
    Già che sei stato così gentile vorrei porti un'altra domanda(ovviamente se hai voglia e tempo di rispondere):
    Il codice del form che ho postato è semplificato.
    Nell'applicativo originale la casella di testo per l'immissione delle date era una casella di tipo datedi bootstrap che ovviamente ho dovuto sostituire con una casella di tipo text, in quanto la precedente mi dava errore nella conversione della data. La cosa mi sembra alquanto strana poiché il tipo di dato che esce da una casella di tipo date è una stringa.
    Sai per caso a cosa è dovuto questo problema?

  7. #7
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,082
    Purtroppo io non conosco Bootstrap, ma nel forum so che c'è chi lo conosce. Eventualmente ho un collega che si occupa proprio di Bootstrap, quindi posso chiedere a lui... però dovresti postare il codice che ti dà errore, così almeno so che cosa fargli vedere.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  8. #8
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Purtroppo io non conosco Bootstrap, ma nel forum so che c'è chi lo conosce. Eventualmente ho un collega che si occupa proprio di Bootstrap, quindi posso chiedere a lui... però dovresti postare il codice che ti dà errore, così almeno so che cosa fargli vedere.


    Ciao.
    Scusa se rispondo con ritardo.
    Questo è il codice:

    codice:
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
    </head>
    <body>
    	<div class="container">
    
    
        <form action="/Prova/Inserimento" method="GET">
          <div class="form-group">
            <label for="nome">Nome</label>
          <input type="text" class="form-control form-control-sm" id="nome" name="nome" placeholder="Nome" required>
          </div>
          <div class="form-group">
            <label for="cognome">Cognome:</label>
            <input type="text" class="form-control form-control-sm" id="cognome" name="cognome" placeholder="Cognome" required>
          </div>
           <div class="form-group">
          <label class="control-label col-sm-2" for="dataNascita">Data di nascita:</label>
          <input type="date" class="form-control" id="dataEmissione" name="dataEmissione">
          </div>
          <button type="submit" class="btn">Invia</button>
        </form>
      </div>
      
    	
    </body>
    </html>
    E questo è l'errore che ottengo nell'utilizzare l'input type date al posto del text:

    java.lang.NullPointerException
    at java.text.SimpleDateFormat.parse(SimpleDateFormat. java:1439)
    at java.text.DateFormat.parse(DateFormat.java:364)
    at utility.ManipolazioneDate.convertiData(Manipolazio neDate.java:17)
    at servlet.Inserimento.doGet(Inserimento.java:45)

  9. #9
    Quote Originariamente inviata da Andreawave Visualizza il messaggio
    java.lang.NullPointerException
    at java.text.SimpleDateFormat.parse(SimpleDateFormat. java:1439)
    at java.text.DateFormat.parse(DateFormat.java:364)
    at utility.ManipolazioneDate.convertiData(Manipolazio neDate.java:17)
    at servlet.Inserimento.doGet(Inserimento.java:45)
    Beh, l'errore "tecnico" mi pare chiaro: stai passando un null in argomento al parse di un DateFormat.
    Ma perché hai un null ... devi verificarlo bene tu.
    AndreaSenior Java developerSCJP 5 (91%) – SCWCD 5 (94%)
    Il mio nuovo sito-blog italiano sulla programmazione: andbin.it

  10. #10
    Ok, chiedo scusa! Il problema del nullpointerException l'ho risolto. Era dovuto ad una mia svista in quanto avevo indicato un id diverso nel codice html.
    Rimane però il seguente problema; l'errore che ottengo è il seguente:
    java.text.ParseException: Unparseable date: "1935-04-13"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at utility.ManipolazioneDate.convertiData(Manipolazio neDate.java:17)
    at servlet.Inserimento.doGet(Inserimento.java:45)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:635)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:742)
    Ha problemi nel fare il parse della data che io passo tramite input type="date", mentre non ho problemi se la data la passo tramite input type="text".
    Ultima modifica di Andreawave; 20-03-2019 a 11:55

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2019 vBulletin Solutions, Inc. All rights reserved.