Date, Time ou Timestamp ... a hora volta 00:00:00 mesmo estando gravada corretamente no banco MySQL

12 respostas
G

Boa tarde!

Estou resgatando uma data no banco de dados MySQL e utilizando SimpleDateFormat para formata-la. Acesso o banco e a data está gravada corretamente
Ex.

No banco >>> 2010-03-07 16:39:22

Quero resgatar assim >>> 07/03/2010 16:39:22

Estou utilizando o código abaixo para o resgate, entretanto a hora sempre fica zerada

07/03/2010 00:00:00

Onde estou errando?? Já usei Time, Timestamp e Date… não funciona!

Obrigado!

/* Cria o objeto "listadao" com o método ListaContato()
         * referênciando a classe ListaContato
         */
        ListaContato listadao = new ListaContato();

        /* Cria a lista com a interface List<> pertencente
         * a classe java.sql.List usando a classe Contato
         * como parâmetro. Usa o objeto "listadao" para 
         * recuperar com o método getLista() os "dados"
         */
        List<Contato> dados = listadao.getLista();

        /* usa o for com parâmetro a classe Contato 
         * dado para dados ou seja para o numero de dados
         * igual a dado continue.
         */

        for (Contato dado : dados){

            System.out.println("Nome: " + dado.getNome());
            System.out.println("Endereço: " + dado.getEndereco());
            System.out.println("Email: " + dado.getEmail());

            Date data = new Date(dado.getData().getTimeInMillis());

            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

            String dataFormatada = sdf.format(data);

            System.out.println("Data: "+ dataFormatada + "\n");

12 Respostas

M

Bem vindo ao fórum!

Creio que o problema não seja na formatação. É mais provável que seja na persistência.

De qualquer forma:

  1. Imprima o valor de dado.getData().getTimeInMillis() e coloque aqui para vermos.

  2. Coloque também o método getLista da classe ListaContato para vermos.

G
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.com.caelum.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 *
 * @author Biffi
 */
public class ListaContato {

    /* faz conexão privada com o banco de dados usando a variável connection
     * e utilizando a classe java.sql.Connection
     */
    private Connection connection;


    public ListaContato(){
        // Objeto de conexão
        this.connection = new ConnectionFactory().getConnection();
    }

    /* usando List<contato> que é uma interface de saída em
     * lista  que pertence a classe java.util.List criamos
     * o método getLista que retornará a lista do banco de
     * dados conforme o comando quey.
     */
    public List<Contato> getLista(){
        try{
            /* cria o objeto contatos no qual é armazenado
             * o retorno do comando query usando mais uma
             * intarfece da classe java.util.List ArrayList<>
             * a qual pega os valores e armazena no vetor.
             */
            List<Contato> dados = new ArrayList<Contato>();

            /* cria objeto "stmt" onde são armazados os valores que serão
             * retornados do banco de dados utilizando o método
             * prepareStatemente("QUERY SQL") que pertence a classe
             * java.sql.PreparedStatemente que usa o objeto "connection"
             * que é responsável pela conexão com o banco de dados */
            PreparedStatement stmt = this.connection.prepareStatement(
                    "select * from contatos");

            /* Armazena no objeto "rs" os resultados das colunas da tabela
             * que esttão no objeto "stmt" usando a interface
             * ResultSet que pertence a classe java.sql.ResultSet
             * usando o método executeQuery() que pertence ao main Java
             */
            ResultSet rs = stmt.executeQuery();

            /* Enquando ouver colunas continue exibindo resultados
             * é o que faz o while() passando como método as colunas
             * armazenadas no objeto "rs" com o método next() que pertence
             * ao main Java
             */
            while (rs.next()){
                /* criando o objeto contato através do método
                 * Contato() que referência a classe Contato.
                 */
                Contato dado = new Contato();
                
                /* Armazenando o nome das colunas cujo os dados
                 * devem ser retornados
                 */
                dado.setNome(rs.getString("nome"));
                dado.setEmail(rs.getString("email"));
                dado.setEndereco(rs.getString("endereco"));
                
                /* Montando o retorno de data através da classe
                 * java.util.Calendar
                 */
                Calendar data = Calendar.getInstance();
                data.setTime(rs.getDate("data"));
                dado.setData(data);
                
                /* Adicionando o objeto contato a lista
                 * List<contato> contatos ou seja adiociona
                 * o resultado do objeto contato em contatos
                 * que são todos os valores de contato
                 */
                dados.add(dado);
            }// fecha while

            /* encerra o objeto "rs" de ResultSet que retornou
             * os dados do comando SQL
             */
            rs.close();

            /* encerra o objeto "stmt" de PreparedStatement que
             * armazenou os dados do comando SQL
             */
            stmt.close();

            /* retorna a variável contatos na qual foi add cada contato
             * através do while
             */
            return dados;
        }// fim do try
            catch (SQLException e){
                throw new RuntimeException(e);
            }// fim do catch
    }// fim do método getLista
}// fim da classe lista
G

1. Imprima o valor de dado.getData().getTimeInMillis() e coloque aqui para vermos.

O valor é >> 1267930800000

M

O problema não é na formatação. O valor 1267930800000 se refere mesmo a uma data com hora 00:00.

Isso significa que o problema está na classe de persistência.

Antes da linha 84 da classe que você colocou acima, adicione:

System.out.println(rs.getDate("data"));

Depois coloque aqui o resultado.

G

2010-03-07
Nome: Tatiane Barreto
Endereço: Rua Arnaldo de Matos, 311
Email: [email removido]
Data: 1267930800000

M

Giovanni Biffi:

Data: 1267930800000

Ou seja: a data resgatada realmente se refere a uma data com horário 00:00. Tem certeza que no banco o valor está certo? Esse valor foi inserido manualmente por você ou foi inserido através do seu programa?

G

Foi inserido através do programa:

Principal

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.com.caelum.jdbc;

import java.sql.Date;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;

/**
 *
 * @author Biffi
 */
public class TestaConexao {

    public static void main (String[] args) throws SQLException{

        /* Cria o objeto "contato" e utiliza método
        Contato() para referenciar a classe Contato
        onde estão os gets e sets : Javabeans que são
        classes que possuem construtor sem argumentos
        e métodos de acesso tipo get e set */
        Contato contato = new Contato();

        /* armazena os dados do contato utilizando
        o método set para cada tipo de dados */
        contato.setNome("Tatiane Barreto");
        contato.setEmail("[email removido]");
        contato.setEndereco("Rua Arnaldo de Matos, 311");

        /* Utiliza a classe java.util.Calendar e usa
         o método getInstance() que retorna a instância do
         objeto */
        contato.setData(Calendar.getInstance());

        /* cria o objeto "dao" e utiliza o método
        ContatoDAO() para referênciar a classe ContatoDAO */
        ContatoDAO dao = new ContatoDAO();

        /* o objeto "dao" é processado pelo método adiciona()
         que pertence a classe ContatoDAO() enviando como
         parâmetro o objeto "contato" sendo assim os objetos
         recebem as seguintes funções:
         contato >> armazenar valores
         dao >> trânsportar os valores de contato até o método adiciona*/
        dao.adiciona(contato);

        // imprime somente o texto
        System.out.println("Gravado!");

        /* Cria o objeto "listadao" com o método ListaContato()
         * referênciando a classe ListaContato
         */
        ListaContato listadao = new ListaContato();

        /* Cria a lista com a interface List<> pertencente
         * a classe java.sql.List usando a classe Contato
         * como parâmetro. Usa o objeto "listadao" para 
         * recuperar com o método getLista() os "dados"
         */
        List<Contato> dados = listadao.getLista();

        /* usa o for com parâmetro a classe Contato 
         * dado para dados ou seja para o numero de dados
         * igual a dado continue.
         */

        for (Contato dado : dados){

            System.out.println("Nome: " + dado.getNome());
            System.out.println("Endereço: " + dado.getEndereco());
            System.out.println("Email: " + dado.getEmail());

            Date data = new Date(dado.getData().getTimeInMillis());

            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

            String dataFormatada = sdf.format(data);

            System.out.println("Data: "+ dado.getData().getTimeInMillis() + "\n");

        } // fim for

    }

}

Classe que insere

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.com.caelum.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;

/**
 *
 * @author Biffi
 */
public class ContatoDAO {
    /* DAO : Data Access Object,  é um padrão para persistência
     de dados que permite separar regras de negócio das regras
     de acesso a banco de dados.
     Numa aplicação que utilize a arquitetura MVC,
     todas as funcionalidades de bancos de dados, tais como
     obter as conexões, mapear objetos Java para tipos de
     dados SQL  ou executar comandos SQL, devem ser feitas
     por classes de DAO.  */

    // Faz conexão privada com o banco usando a variável privada connection.
    private Connection connection;

    /* o método ContatoDAO() cria um objeto "connection" de conexão
     usando a classe ConnectionFactory na qual existe
     o método getConnection() */
    public ContatoDAO(){
        // Objeto de conexão
        this.connection = new ConnectionFactory().getConnection();
    }
    public void adiciona(Contato contato){
        //Comando SQL é declarado com String
        String sql = "insert into contatos" +
                "(nome, email, endereco, data)" +
                "values (?,?,?,?)";

        /* cria objeto "stmt" onde são armazados os valores que serão
        incluidos no banco de dados utilizando o método
        prepareStatemente(sql) que pertence a classe
        java.sql.PreparedStatemente que usa o objeto "connection"
        que é responsável pela conexão com o banco de dados */
        try{
            PreparedStatement stmt = connection.prepareStatement(sql);

            /* seta os valores para incluir no objeto "stmt"
            ou seja dá localização e valor diferente para
            cada ponto de interrogação do comando SQL */
            stmt.setString(1, contato.getNome());
            stmt.setString(2, contato.getEmail());
            stmt.setString(3, contato.getEndereco());

            /* formata valor de data para a compreensão do
            banco de dados utilizando o método Date() pertencente
            a classe java.sql.Date */
            stmt.setTimestamp(4, new Timestamp( contato.getData().getTimeInMillis() ));

            /* Inicia e encerra a execução do objeto "stmt"
            utilizando os métodos execute() e close()
            pertencentes a classe main do java */
            stmt.execute();
            stmt.close();
        } catch (SQLException e){
            /* trata erros de conexão
            clausula adiciona automaticamente no PreparedStatement
            na instrução stmt.close() */
            throw new RuntimeException(e);
        }
    }
}

Classe Set e Get

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.com.caelum.jdbc;

import java.sql.Date;
import java.util.Calendar;


/**
 *
 * @author Biffi
 */
public class Contato {

    /* Classe responsável por armarzenar e recuperar
    as informações do banco de dados usando os métodos
    set( função: armarzenar ) e get( função: recuperar)
    para cada variável. */

    private long id;
    private String nome;
    private String email;
    private String endereco;
    private Calendar data;

    public Calendar getData() {
        return data;
    }

    public void setData(Calendar data) {
        this.data = data;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEndereco() {
        return endereco;
    }

    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

}
M

O campo “data” do banco é de que tipo?

G

DATETIME no MySQL

G

M

Pois é… um campo do tipo DATE armazena só a data (sem horário).

No método getLista você viu como você pega o campo “data”? Com o método getDate de PreparedStatement.

Isso quer dizer que na hora de resgatar ele está interpretando o campo como se fosse DATE.

A solução? Troque sua linha 84 por:

data.setTime(rs.getTimestamp("data"));

Isso fará que ele interprete como TIMESTAMP (ou DATETIME) considerando o horário.

Última coisa: a classe DAO serve tanto para inserir como para resgatar dados. O método getLista() deveria estar nela e a classe ListaContato nem precisaria existir.

G

MUITO OBRIGADO! ficou perfeito agora… criei a classe ListaContato para separar a “listagem” da “inclusão”, não sei se é correto mas acho que permite uma manutenção mais objetiva talvez… comecei a estudar Java agora e estou estudando uma apostila da Caelum e o livro Java Como Programar 6ª Edição… não entendo tudo bem claramente, como se dá as comunicações e o funcionamento das classes existentes. Agradeço por ter utilizado o seu tempo para me ajudar…

Criado 7 de março de 2010
Ultima resposta 7 de mar. de 2010
Respostas 12
Participantes 2