Pessoal, no sistema aqui da empresa existe um método que calcula datas com GregorianCalendar. Nós já havíamos testado, usado JUnit para testes automáticos, e tudo havia funcionado perfeitamente.
Já há algum tempo, o sistema foi implantado em um cliente, e lá ocorreu um problema de travamento que, debugando, descobrimos que ocorria justamente em nossa classe que calculava datas. Em um método que testava se um dia era ou não feriado, ocorria uma soma de 1 dia em uma data e essa soma não ocorria. Ou seja, ele tentava somar 1 dia a 19/02/2005 e retornava 19/02/2005. Testamos aqui em nossas máquinas e o erro não ocorreu. Criamos um programa pequeno apenas com a classe para testar e o problema mais uma vez ocorreu apenas nas máquinas do cliente, não nas nossas.
O método usa o esquema de milissegundos para calcular a data. Eu fiz um teste usando o método add() do GregorianCalendar, testei na minha máquina e deu certo. Testei em uma máquina que pegamos emprestada do cliente e deu errado.
O programa que usei para testar segue abaixo:
package testeData;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.GregorianCalendar;
/**
* <B> DoomData </B>
*
* @author wilerson
* @version 07/01/2005
*/
public class DoomData {
public static void main( String[] args ) {
File arq1 = new File( "arq1.txt" );
File arq2 = new File( "arq2.txt" );
try {
arq1.createNewFile();
arq2.createNewFile();
BufferedWriter writer = new BufferedWriter( new FileWriter( arq1 ) );
for ( int i = 1; i < 370; i++ ) {
writer.write( calcula2( "01/01/2005", i ) + "\r\n" );
}
writer.close();
writer = null;
writer = new BufferedWriter( new FileWriter( arq2 ) );
String sdata = "01/01/2005";
for( int i = 1; i < 370; i++ ) {
sdata = calcula2( sdata, 1 );
writer.write( sdata + "\r\n" );
}
writer.close();
}
catch( IOException e ) {
e.printStackTrace();
}
}
public static String calcula2( String sdata1, int idias ) {
GregorianCalendar gc = new GregorianCalendar( Integer.parseInt( sdata1.substring( 6, sdata1.length() ).trim().replace( ' ', '0' ) ),
Integer.parseInt( sdata1.substring( 3, 5 ).trim().replace( ' ', '0' ) ) - 1,
Integer.parseInt( sdata1.substring( 0, 2 ).trim().replace( ' ', '0' ) ) );
gc.add( GregorianCalendar.DAY_OF_MONTH, idias );
String sdataFormat = "";
String sdia = gc.get( GregorianCalendar.DAY_OF_MONTH ) < 10 ?
"0" + String.valueOf( gc.get( GregorianCalendar.DAY_OF_MONTH ) ) :
String.valueOf( gc.get( GregorianCalendar.DAY_OF_MONTH ) );
String smes = gc.get( GregorianCalendar.MONTH ) + 1 < 10 ?
"0" + String.valueOf( gc.get( GregorianCalendar.MONTH ) + 1 ) :
String.valueOf( gc.get( GregorianCalendar.MONTH ) + 1 );
String sano = String.valueOf( gc.get( GregorianCalendar.YEAR ) );
sdataFormat = sdia + "/" + smes + "/" + sano;
return sdataFormat;
}
}
Reparem que é bem simples, eu o fiz em uns dez minutos só para testar. Na máquina do cliente, ele gerou o arq1.txt corretamente (somando 1 em 1 até 05/01/2006), mas no arq2.txt ele parou de somar a partir de 08/10/2005. Ou seja, ele somou normalmente até 07/10/2005, mas a partir de 08/10/2005, passou a repetir essa data.
Existe algum bug conhecido na GregorianCalendar que poderia gerar um comportamento desse tipo?
A propósito, a máquina do cliente tem as seguintes características:
Intel Celeron 2.0 GHZ
256 MB RAM
Windows 2000 5.00.2195 Service Pack 4
E a versão da J2RE, tanto nas máquinas daqui quanto nas do cliente, é J2RE 1.4.2_04-b05 .
Se puderem me ajudar, obrigado. :¬)