[RESOLVIDO] Java calcula diferença entre datas errado

7 respostas
eliangela

Olá pessoa!

Há alguns dias eu postei um tópico aqui pedindo pra calcular a diferença entre datas em dias, ou seja, informo a data 01/01/1900 como data inicial e quero saber quantos dias rolaram até hj.
O tópico foi respondido, mas estou encontrando problemas aqui no meu trampo por causa de um bug.

Segue meu código:
public class Calendario {

    private static final GregorianCalendar FIRST_DAY = new GregorianCalendar(2009, 6, 30, 0, 0, 0);

    public static int getDays(int ano, int mes, int dia) {
        GregorianCalendar data = new GregorianCalendar(ano, mes, dia, 0, 0, 0);
        int elapsed = 0;
        GregorianCalendar g1 = FIRST_DAY;
        GregorianCalendar gc1, gc2;
        if (data.after(g1)) {
            gc2 = (GregorianCalendar) data.clone();
            gc1 = (GregorianCalendar) g1.clone();
        } else {
            gc2 = (GregorianCalendar) g1.clone();
            gc1 = (GregorianCalendar) data.clone();
        }
        gc1.clear(Calendar.MILLISECOND);
        gc1.clear(Calendar.SECOND);
        gc1.clear(Calendar.MINUTE);
        gc1.clear(Calendar.HOUR_OF_DAY);
        gc2.clear(Calendar.MILLISECOND);
        gc2.clear(Calendar.SECOND);
        gc2.clear(Calendar.MINUTE);
        gc2.clear(Calendar.HOUR_OF_DAY);
        while (gc1.before(gc2)) {
            gc1.add(Calendar.DATE, 1);
            elapsed++;
        }
        return elapsed;
    }

    public static void main(String[] args) {
        System.out.println(getDays(2009, 7, 1));
    }
}
Eu mudei o valor da constante FIRST_DAY para a data 30/06/2009 e pedi para meu programa me informar quantos dias dá até a data 01/07/2009, mas meu método retorna 2 dias.

Não sei qual é o problema. Tenho certeza que não é meu código, pois testei vários códigos deste site: [url]http://www.java2s.com/Code/Java/Development-Class/Calendar-Date.htm[/url] e não dá certo.

Existe alguma maneira de contornar esta situação?

Obrigada

7 Respostas

M

Dá uma olhada nesse link

http://www.exampledepot.com/egs/java.util/CompDates.html

ignacio83

Só uma coisa. Vc sabe que o mês começa como 0 em Gregorian Calendar certo?

Portanto JAN = 0; FEV = 1, MAR = 2 etc etc…

Talvez possa ser esse o seu problema…

eliangela

ignacio83:
Só uma coisa. Vc sabe que o mês começa como 0 em Gregorian Calendar certo?

Portanto JAN = 0; FEV = 1, MAR = 2 etc etc…

Talvez possa ser esse o seu problema…

Olha… acredito que não seja isso, porque esse cálculo retorna 1 dia a mais na virada no mes. E, se não me engano, quando vira o ano, dá diferença de 2 dias.

T

new GregorianCalendar (2009, 6, 30, 0, 0, 0) representa o dia 30 de JULHO (07) de 2009.
GregorianCalendar

E de fato, julho tem 31 dias.

eliangela

eliangela:
ignacio83:
Só uma coisa. Vc sabe que o mês começa como 0 em Gregorian Calendar certo?

Portanto JAN = 0; FEV = 1, MAR = 2 etc etc…

Talvez possa ser esse o seu problema…

Olha… acredito que não seja isso, porque esse cálculo retorna 1 dia a mais na virada no mes. E, se não me engano, quando vira o ano, dá diferença de 2 dias.

Desculpe!
Tinha entendido errado o que vc quis dizer…
no lugar de

GregorianCalendar FIRST_DAY = new GregorianCalendar(2009, 6, 30, 0, 0, 0);

devo colocar:

GregorianCalendar FIRST_DAY = new GregorianCalendar(2009, Calendar.JUNE, 30, 0, 0, 0);

Entendi qual era o problema… O engraçado é que neste link que eu postei, estava do mesmo jeito que eu estava fazendo :frowning:

Obrigada a todos!!!

eliangela

Agora segue a minha classe pronta!
O lance é o seguinte:
Eu tenho uma data inicial padrão: 01/01/1930 e quero fazer cálculos baseando-se nesta data.
- saber quantos dias correram desde essa data e,
- informar uma quantidade de dias e o método retornar a data.

Apesar de eu ter colocado [RESOLVIDO] no tópico, eu ainda estava com problemas, pois se eu informasse um número que deveria me retornar 01/01/2009, o meu código retornava 30/12/2008. Daí eu coloquei "+ 1" em i[2] = ini.getDate() + 1; e meu código começou a mostrar 32/12/2008. Coloquei os métodos que estão depracated:
i[0] = ini.getYear() + 1900;
        i[1] = ini.getMonth() + 1;
        i[2] = ini.getDate() + 1;
porque com a classe GregorianCalendar estava impossível de corrigir.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * @since 1.6
 * @author Eliangela Menezes Palharini
 */
public class Calendario {

    private static final String DATE = "yyyyMMdd";
    private static final String TIME = "HHmmss";
    private static final GregorianCalendar FIRST_DAY = new GregorianCalendar(1930, Calendar.JANUARY, 1, 0, 0, 0);

    public static String getSystemDateTime() {
        Calendar cal = Calendar.getInstance();
        Date date = cal.getTime();
        SimpleDateFormat sData = new SimpleDateFormat(DATE);
        SimpleDateFormat sTime = new SimpleDateFormat(TIME);
        return sData.format(date).substring(0, 8) + cal.get(Calendar.DAY_OF_WEEK) + sTime.format(date);
    }

    public static int getDiaSemana(int year, int month, int day) {
        GregorianCalendar g = new GregorianCalendar(year, month, day, 0, 0, 0);
        return g.get(Calendar.DAY_OF_WEEK);
    }

    public static int getDias(int ano, int mes, int dia) {
        GregorianCalendar inicio = FIRST_DAY;
        Calendar now = new GregorianCalendar(ano, (mes - 1), dia);

        long dif = now.getTimeInMillis() - inicio.getTimeInMillis();
        return (int) (1 + dif / (24 * 60 * 60 * 1000));
    }

    public static int[] getData(int numero) {
        int i[] = new int[3];
        int dia = FIRST_DAY.get(Calendar.DATE);
        int mes = FIRST_DAY.get(Calendar.MONTH);
        int ano = FIRST_DAY.get(Calendar.YEAR);
        GregorianCalendar today = new GregorianCalendar(ano, mes, dia, 0, 0, 0);
        today.add(Calendar.DATE, numero - 1);
        Date ini = today.getTime();
        i[0] = ini.getYear() + 1900;
        i[1] = ini.getMonth() + 1;
        i[2] = ini.getDate() + 1;
        if (i[2] == 32) {
            i[2] = 1;
            if (i[1] == 12) {
                i[1] = 1;
                i[0] = i[0] + 1;
            } else {
                i[1] = i[1] + 1;
            }
        }
        return i;
    }

}

Aceito sugestões de melhorias!

Até mais pessoal!!

Fernando_Generoso_da

um jeito “Se vira nos 30” de fazer…

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;

public class DiferencaDatas {

	public static void main(String args[]) {
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();

		c1.set(Calendar.YEAR, 2009);
		c1.set(Calendar.MONTH, Calendar.JANUARY);
		c1.set(Calendar.DAY_OF_MONTH, 1);
		c1.set(Calendar.HOUR, 0);
		c1.set(Calendar.MINUTE, 0);
		c1.set(Calendar.SECOND, 0);
		c1.set(Calendar.MILLISECOND, 0);
		c1.set(Calendar.AM_PM, Calendar.AM);

		System.out.println(c1.getTime());

		c2.set(Calendar.YEAR, 2009);
		c2.set(Calendar.MONTH, Calendar.DECEMBER);
		c2.set(Calendar.DAY_OF_MONTH, 31);
		c2.set(Calendar.HOUR, 23);
		c2.set(Calendar.MINUTE, 59);
		c2.set(Calendar.SECOND, 59);
		c2.set(Calendar.MILLISECOND, 99);
		c2.set(Calendar.AM_PM, Calendar.AM);

		System.out.println(c2.getTime());

		long dif = c2.getTime().getTime() - c1.getTime().getTime();

		long constante = 1000 * 60 * 60 * 24;

		BigDecimal bd = new BigDecimal(dif);
		BigDecimal value = bd.divide(new BigDecimal(constante), RoundingMode.FLOOR);
		System.out.println(value.doubleValue());

	}

}

Mas aconselho a dar uma olhada na joda-time…

Fernando

Criado 23 de junho de 2009
Ultima resposta 24 de jun. de 2009
Respostas 7
Participantes 5