Problema na conversão de data feita pelo Vraptor3?

6 respostas
A

olá,

estou fazendo um sistema web com Vraptor3, Hibernate3.x e PostgreSql 8.3:

Tenho um objeto tarifa no sistema. E neste  2 atributos de log:

@Temporal(TemporalType.TIMESTAMP)

private Date dataHoraCadastro;

@Temporal(TemporalType.TIMESTAMP)

private Date dataHoraUltimaAlteracao;
Fiz o Hibernate gerar o banco de dados e saiu:

COLUMN datahoracadastro timestamp without time zone;

COLUMN datahoraultimaalteracao timestamp without time zone;

Tenho 3 operações na controller de tarifas:

  • form (view que uso para cadastro e alteração)
  • cadastrar
  • alterar

em cadastrar(Tarifa tarifa) e em alterar(Tarifa tarifa), onde pego a tarifa da view via método Post, salvo no bd.

Quando a operação é de alteração coloco na view o campo de dataHoraCadastro

<input type="hidden" name="tarifa.dataHoraCadastro" value="<fmt:formatDate pattern="dd/MM/yyyy hh:mm:ss" value="${tarifa.dataHoraCadastro}" type="both" />" />

que imprime por exemplo:

Quando o usuáriuo clica em ‘enviar’ na view vi que no banco de dados salva sempre sem a parte de horário: por exemplo 2010-04-21 00:00:00

Pensei que fosse algum erro meu no uso da tagLib fmt ou no mapeamento de dados para salvar no bd.

Mas quando imprimi na controller com system.out.println, antes da operação no bd, vi que já veio sem a parte do horário.

Será algum problema na conversão da data feita pelo Vraptor3 ??

Como posso resolver isso ?

Abçs,
Asdias

6 Respostas

Lucas_Cavalcanti

se o seu Tarifa.getDataHoraCadastro retorna um Date ou um Calendar, o VRaptor não faz nada…

de qqer forma, se ele retorna um Calendar vc deveria fazer:

<fmt:formatDate pattern="dd/MM/yyyy hh:mm:ss" value="${tarifa.dataHoraCadastro.time}"/>
G

asdias, primeiramente acho que há um erro no sei código. Isso não tem nada a ver com seu problema relatado aqui, porém causa um erro de sintaxe do HTML. Tem dois atributos VALUE nessa tag.

<input type="hidden" name="tarifa.dataHoraCadastro" value="<fmt:formatDate pattern="dd/MM/yyyy hh:mm:ss" value="${tarifa.dataHoraCadastro}" type="both" />" />

Mas enfim, falando no seu problema, o converter usado para o vraptor para converter datas é o LocalBasedDateConverter, e esse componente é baseado apenas na data, e não date-time.

Uma solução temporária que eu vejo é usar o seguinte componente dentro da sua aplicação. Note que ele vai sobrescrever o converter padrão fazendo assim a conversão da data + tempo.

@Convert(Date.class)
@RequestScoped
public class LocaleBasedDateConverter implements Converter<Date> {

    public Date convert(String value, Class<? extends Date> type, ResourceBundle bundle) {
        if (value == null || value.trim().isEmpty()) {
            return null;
        }
        
        SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
        try {
            return fmt.parse(value);
        } catch (ParseException e) {
			throw new ConversionError(MessageFormat.format(bundle.getString("is_not_a_valid_date"), value));
        }
    }
}
G

Lucas Cavalcanti:
se o seu Tarifa.getDataHoraCadastro retorna um Date ou um Calendar, o VRaptor não faz nada…

de qqer forma, se ele retorna um Calendar vc deveria fazer:

<fmt:formatDate pattern="dd/MM/yyyy hh:mm:ss" value="${tarifa.dataHoraCadastro.time}"/>

Lucas, ou eu ou você entendeu errado. A impressão que eu tive é que ele quer que grave no banco timestamp ao invés de only-date.

Lucas_Cavalcanti

o formatDate só trata Date, e não Calendar (se eu não me engano)… e o getTime do Calendar retorna um Date =)

A

Olá pessoal,

no código que eu apresentei não tinha erro, os 2 values eram: 1o. do input text, 2o. da taglib (fmt). Desculpem, me esqueci de marcar o código-fonte com a tag 'code', aqui do forum.

Fiz o conversor indicado, mas como tenho partes de minha aplicação que uso data no formato dd/mm/aaaa e outras no formato dd/mm/aaaa fiz uma pequena alteração no conversor dado: acresento zeros na parte do tempo, quando recebo somente a parte da data.

Ficou assim
@Convert(Date.class)  
 @RequestScoped  
 public class LocaleBasedDateConverter implements Converter<Date> {  
   
     public Date convert(String value, Class<? extends Date> type, ResourceBundle bundle) {  

    	 if (value.length()==10){
    		 value = value.concat(" 00:00:00.000");
    	 }
    	 
    	 
    	 if (value == null || value.trim().isEmpty()) {  
             return null;  
         }  
           
         SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");  
         try {  
        	 return fmt.parse(value);  
         } catch (ParseException e) {  
             throw new ConversionError(MessageFormat.format(bundle.getString("is_not_a_valid_date"), value));  
         }  
     }  
 }

Este conversor sobrescreveu o que vem no Vraptor. Não quero que hava efeitos colaterias indeseajados na aplicação...
estou agora em testes.

obrigado,
Abçs,

G

Se não me engano o Joda-time possui classes para Date, Time e DateTime. Se você puder em seu projeto usá-las me parece ficar bem elegante, embora a sua solução seja algo que não dará problemas.

Abraços

Criado 21 de abril de 2010
Ultima resposta 22 de abr. de 2010
Respostas 6
Participantes 3