Estou com problemas com a classe java.util.Calendar. O código abaixo está gerando “java.lang.IllegalArgumentException: HOUR_OF_DAY” no SLED10 (Suse Linux Enterprise Desktop 10).
No jdk1.6.0_10 o erro acontece após a data 10 de Outubro de 2009;
No jdk1.6.0_12, jdk1.6.0_14, jdk1.6.0_16 o erro acontece após a data 17 de Outubro de 2009;
import java.util.*;
public class CalTeste {
public static void main(String[] args) {
Calendar calendar = new GregorianCalendar(new Locale("pt", "BR"));
calendar.setLenient(false);
calendar.set(2009, 0, 1); // (01/01/2009)
Date lastDate = calendar.getTime();
while(true){
calendar.add(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date date = null;
try {
date = calendar.getTime();
if(calendar.get(Calendar.YEAR)>=2010){ //Para em 2010
break;
}
} catch (Exception e) {
e.printStackTrace();
System.err.println("Erro! Última data válida: " + lastDate + ", Valor próximo dia: " + date);
break;
}
lastDate = date;
}
}
}
Alguém saberia dizer qual o problema com o código acima? É como se o java não aceitasse a hora “zero” no dia 11/10/2009 (jdk1.6_10) e 18/10/2009 (outros jdk’s)…
É isso mesmo… Quando eu tiro o horário de verão da máquina, o erro não acontece mais. Ok, até aí eu aceito como comportamento padrão esperado da JVM. O que eu não aceito é que se eu colocar:
Calendar c = new GregorianCalendar(2009, 1, 1); //01 de fevereiro de 2009
System.out.println(c.getActualMaximum(Calendar.DAY_OF_MONTH));
O código acima imprime 28, perfeito!
Agora com o código:
c = new GregorianCalendar(2009, 9, 18);
System.out.println(c.getActualMinimum(Calendar.HOUR_OF_DAY));
O código acima imprime 0, em vez de imprimir 1 (já que essa é a data que não existe a hora zero). Isso não seria um bug?
public int getActualMinimum(int field) {
if (field == DAY_OF_MONTH) {
GregorianCalendar gc = getNormalizedCalendar();
int year = gc.cdate.getNormalizedYear();
if (year == gregorianCutoverYear || year == gregorianCutoverYearJulian) {
long month1 = getFixedDateMonth1(gc.cdate, gc.calsys.getFixedDate(gc.cdate));
BaseCalendar.Date d = getCalendarDate(month1);
return d.getDayOfMonth();
}
}
return getMinimum(field);
}
...
public int getMinimum(int field) {
return MIN_VALUES[field];
}
...
static final int MIN_VALUES[] = {
BCE, // ERA
1, // YEAR
JANUARY, // MONTH
1, // WEEK_OF_YEAR
0, // WEEK_OF_MONTH
1, // DAY_OF_MONTH
1, // DAY_OF_YEAR
SUNDAY, // DAY_OF_WEEK
1, // DAY_OF_WEEK_IN_MONTH
AM, // AM_PM
0, // HOUR
0, // HOUR_OF_DAY
0, // MINUTE
0, // SECOND
0, // MILLISECOND
-13*ONE_HOUR, // ZONE_OFFSET (UNIX compatibility)
0 // DST_OFFSET
};
...
Ou seja, é um valor fixo.
É o tipo de bug que se você reportar à Sun, eles vão simplesmente dizer que é “won’t fix” porque irá causar uma regressão de desempenho.
É fd… O jeito é colocar um try/catch e adicionar +1 na hora quando capturar a exceção, já que a API não nos dá uma maneira confiável de setar a hora mínima do dia… Espero q a nova API de datas do java 1.7 resolva isso. De qq forma, muito obrigado pela ajuda e atenção, cara! Valeu!