GregorianCalendar exibe o mês errado

Pessoal,

tenho o seguinte trecho de código:

GregorianCalendar data = new GregorianCalendar(); data.set(2003, 11, 22); SimpleDateFormat formatador = new SimpleDateFormat("dd/MM/yyyy"); System.out.println(formatador.format(data.getTime()));

No entanto, a saída desse programa é:

22/12/2003

Por que o mês exibido é dezembro se eu defini como novembro?

O campo do mês no calendar vai de 0 (janeiro) até 11 (dezembro). Quando você definiu 11, estava definindo em dezembro.

Também achei uma droga terem feito assim.

[quote=itiburski]Pessoal,

No entanto, a saída desse programa é:

22/12/2003

Por que o mês exibido é dezembro se eu defini como novembro?[/quote]

Meses do ano iniciam em zero (Janeiro) e terminam em onze(Dezembro), na classe Calendar. Utilize as constantes que definem os meses.

GregorianCalendar data = new GregorianCalendar();
data.set(2003, Calendar.NOVEMBER, 22);

[quote=ViniGodoy]O campo do mês no calendar vai de 0 (janeiro) até 11 (dezembro). Quando você definiu 11, estava definindo em dezembro.

Também achei uma droga terem feito assim.[/quote]

Pois é, ficou estranho mesmo. Mas enfim, obrigada pela resposta.

Outra coisa, se eu receber a data por um request, tem alguma classe ou método que me auxilie a converter esse valor para o tipo GregorianCalendar ou eu vou ter que desmembrar a string e chamar o método set()?

converter String para GregorianCalendar:

String dataString = request.getParameter("data"); //supondo que a data esteja em dd/mm/yyyy DateFormat formatador = new SimpleDateFormat("dd/MM/yyyy"); Calendar data = new GregorianCalendar(); try{ data.setTime(formatador.parse(dataString)); } catch(ParseException e) { e.printStackTrace(); }

ps: acostume-se a declarar variáveis com o supertipo.
NO: GregorianCalendar data = new GregorianCalendar();
YES: Calendar data = new GregorianCalendar();

boa sorte!

Na verdade terminam no 12 (e não no 11). Tem o decimo terceiro mes, o Calendar.UNDECIMBER

[quote=ziegfried]ps: acostume-se a declarar variáveis com o supertipo.
NO: GregorianCalendar data = new GregorianCalendar();
YES: Calendar data = new GregorianCalendar();

boa sorte![/quote]

Hmmm… Farei isso. Mas me diga uma coisa, qual o ganho que se tem em declarar as variáveis com o supertipo?

Obrigada.

O ganho é o encapsulamente, por exemplo vc pode trabalhar com um greagoriancalendar, japão imperial, atravez das assinaturas dos métodos da classe abstrata Calendar

Melhor que

Calendar data = new GregorianCalendar(); 

é

Calendar data = Calendar.getInstance();

pelo fato de calendar ser uma “locale-sensitive classes”, ou seja, pega sua instancia correta atravez do objeto locale.

No caso das collections a vantagem de se trabalhar com o supertipo é mais clara. Por exemplo, no caso das listas, você tem o ArrayList e o LinkedList além de wrappers para sincronização e imutabilidade de suas próprias listas. É muito fácil trocar de implementação, mesmo no meio do projeto, pois embora as implementações sejam diferentes o comportamento das coleções entre si não varia. Este tópico explica isso com mais detalhes.

Embora essa seja realmente uma boa dica, não vejo grandes vantagens para o caso dos calendários. Eu particularmente faço isso, mas só porque GregorianCalendar não me dá nenhum método adicional mais facilitado.

Eu citaria algumas razões:

  1. Embora o tempo seja igual para todo mundo, a forma que se trabalha com um calendário é muito diferente. Ou seja, muito provavelmente um código feito para um calendário gregoriano não funcionará para o calendário japonês, e vice-versa;
  2. Acredito que em 90% dos casos, não há interesse de suportar outro tipo de calendário e é preferível ter uma implementação clara do que algo genérico e muito mais confuso.

Na minha opinião, seria realmente interessante que a Sun disponibilizasse algo mais fácil para o GregorianCalendar, e não nos forçasse a trabalhar de forma genérica, a menos que isso fosse um requisito explícito do projeto. Métodos para determinar dias úteis ou mesmo getters mais agradáveis seriam bastante práticos, aumentariam a legibilidade do código e o tornariam menos sujeito a erros.

O negócio é ficar torcendo para a JSR-310 ser logo aprovada e colocada no SDK. E enquanto isso, ir usando alternativas de terceiros, como a JODA.

Se quiserem mais uma ampla discussão sobre o calendar, podem também dar uma olhada no meu post coisas que odeio em java.