Posts Tagged ‘TimeZone’

O que um TimeZone pode fazer por você

Posted in Notícias on February 9th, 2010 by Fábio Queiroz – Be the first to comment

As vezes, o uso de algumas combinações pregam uma grande peça.

Neste post, vou expor algo que acontece quando se usa ICEFaces para manipular datas através do componente selectInputDate combinado com o conversor convertDateTime.

O uso do trecho de código abaixo…

<ice:selectInputDate id="dataInicio"
    renderMonthAsDropdown="true" renderYearAsDropdown="true"
    title="Selecione a Data" renderAsPopup="true"
    required="true" value="#{meuBackingBean.dataInicio}"
    partialSubmit="true">
    <f:convertDateTime pattern="dd/MM/yyyy HH:mm:ss"/>
</ice:selectInputDate>

… produz um resultado BEM DIFERENTE do trecho de código abaixo.

<ice:selectInputDate id="dataInicio"
    renderMonthAsDropdown="true" renderYearAsDropdown="true"
    title="Selecione a Data" renderAsPopup="true"
    required="true" value="#{meuBackingBean.dataInicio}"
    partialSubmit="true">
    <f:convertDateTime pattern="dd/MM/yyyy"/>
</ice:selectInputDate>

E quando digo diferente, digo da pior maneira possível.

Antes de mostrar o resultado, perceberam a diferença entre as implementações?

A única diferença está na definição do pattern na tag convertDateTime.

Suponhamos que neste objeto seja selecionado a data de 03/02/2010, e isto foi feito as 17h52.

Para o trecho com o pattern indicando dd/MM/aaaa HH:mm:ss, o resultado da definição do atributo dataInicio no Backing Bean é “setDataInicio=Wed Feb 03 17:52:28 BRST 2010″. Correto, se o componente não tivesse exibido estas mesmas informações no input com o horário 2h a frente.

Para o trecho com o pattern indicando dd/MM/aaaa, o resultado da definição do atributo dataInicio no Backing Bean é “setDataInicio=Wed Feb 02 22:00:00 BRST 2010″. Errado, bem errado. Notem que aqui o componente, por algum motivo, criou ou formatou a data/hora usando o timezone GMT e subtraiu 2h (já que estamos no timezone America/Sao_Paulo).

O que fazer para solucionar isso?

Para resolver esta questão será necessário adicionar o atributo timeZone no formatador convertDateTime.

<ice:selectInputDate id="dataInicio"
    renderMonthAsDropdown="true" renderYearAsDropdown="true"
    title="Selecione a Data" renderAsPopup="true"
    required="true" value="#{meuBackingBean.dataInicio}"
    partialSubmit="true">
    <f:convertDateTime pattern="dd/MM/yyyy" timeZone="#{meuBackingBean.timeZone}"/>
</ice:selectInputDate>

Neste caso, adicionamos #{meuBackingBean.timeZone} como valor do atributo timeZone.Por algum motivo, esta definição torna-se obrigatória para que a data não seja criada com horário incorreto.

No Backing Bean, o que devemos implementar é:

@Component
@scope("session")
public class MeuBackingBean.... {

private java.util.Timezone timeZone = TimeZone.getDefault();
...

public TimeZone getTimeZone() {
    return this.timeZone;
}

}