IllegalArgumentException: HOUR_OF_DAY [RESOLVIDO]

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)…

Esse dia é o dia da virada do horário de verão. Pelo que imagino, ele só aceita 01:00:00 nesse dia.

É 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?

Dando uma olhada em GregorianCalendar.java:

    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!