Calcular Datas Futuras

Senhores,

Alguém teria ideia de como eu posso implementar, uma funcionalidade de agendamento onde eu posso dizer por exemplo que "quero lançar mais 5 agendamentos semanais em toda quinta-feira? ou “quero lancar mais 5 agendamento mensais todo dia 05” ?

Meu projeto é com VRaptor.

Alguém poderia ajudar?

Obrigado.

Tem uma biblioteca que faz isso, é o quartz.

Caro jaboot, acho que expliquei mal o problema.

Eu tenho um lançamento de uma “Conta a Pagar” pro dia 10/03/2012, por exemplo.

Como essa conta é fixa, eu quero que ela se repita por mais 10 meses no mesmo dia 10, ou então por mais 10 semanas em todo sábado.

Como eu calculo essas próximas datas?

Obrigado!

o método add do GregorianCalendar não te atende ?

cerli

“Conta a Pagar” pro dia 10/03/2012…

eu faço assim:

pego o dia de vencimento: 10
pego o mes que tá ai: 03

faço um loop com o mês e vou incrementando ele.

[code]String data = “10/03/2012”;

int dia = Integer.parseInt(data.substring(0,2));
int mes = Integer.parseInt(data.substring(3,5));
int ano = Integer.parseInt(data.substring(6,10));

//se é pra 5 meses consecutivos:
int mesParada = mes+5;
String proximaData = null;

while (mes<=mesParada){
++mes;
proximaData = dia + “/” + mes+ “/” + ano;

//cuidado com anos bissextos caso o dia seja 29, com meses que não tem 31, e cuidado se o mes de parada ultrapassar 12, ai vc vai ter que incrementar o ano.

}[/code]

Sim, pro calculo de mês está praticamente igual ao que eu consegui implementar.

Estou me perdendo mais é para calcular as semanas, no caso de lançamentos semanais, toda segunda-feira por exemplo.

eu faria algo assim:

import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtils
{
	public Date addDate(int field, int amount, Date origDate)
	{
		GregorianCalendar gcal = new GregorianCalendar();
		
		try
		{
			gcal.setTime(origDate);
			gcal.add(field, amount);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
		return ( new Date(gcal.getTime().getTime()) );
	}
}

e usaria assim:

			DateUtils dateUtils = new DateUtils();
			
			String data = "10/02/2012";
			Date d1 = new SimpleDateFormat("dd/MM/yyyy").parse(data);
			
			Date d2 = dateUtils.addDate(Calendar.MONTH, 1, d1);
			System.out.println("Data orig: " + d1);
			System.out.println("Data +1 mes: " + d2);
			
			System.out.println("");

			d2 = dateUtils.addDate(Calendar.DAY_OF_MONTH, 30, d1);
			System.out.println("Data orig: " + d1);
			System.out.println("Data +30 dias: " + d2);

			System.out.println("");
			
			d2 = dateUtils.addDate(Calendar.WEEK_OF_MONTH, 2, d1);
			System.out.println("Data orig: " + d1);
			System.out.println("Data +2 semana: " + d2);

a saída é:

Data orig: Fri Feb 10 00:00:00 BRST 2012
Data +1 mes: Sat Mar 10 00:00:00 BRT 2012

Data orig: Fri Feb 10 00:00:00 BRST 2012
Data +30 dias: Sun Mar 11 00:00:00 BRT 2012

Data orig: Fri Feb 10 00:00:00 BRST 2012
Data +2 semana: Fri Feb 24 00:00:00 BRST 2012

também funciona se você quiser subtrair datas, é só passar o amount negativo, para subtrair 2 meses, faz assim:

Date d2 = dateUtils.addDate(Calendar.MONTH, -2, d1);

espero que ajude

Estou precisando implementar a mesma coisa.
Preciso repetir todos os dias da semana/semanalmente/mensalmente/anualmente lançamentos, como no Google Agenda.

Em alguns casos eu preciso de uma condição de parada (repetir até data X).
Existe uma API pra isso ou eu tenho que implementar desmembrando o dia, mês e ano da data??
Esse quartz, pelo que li, não atende ao caso.

Use a dica do aechiara que resolve!

Estou usando, mas não quero reinventar a roda se ela já tiver sido inventada (o que eu imagino ser possível e provável).
Enfim, já estou implementando o que preciso (como tenho feito sempre que tenho um problema), mas estou com uns probleminhas…

Tá dando dead code no if. Por que?

GregorianCalendar gCalendar = new GregorianCalendar();
Date data = new Date();
gCalendar.setTime(data);
if (GregorianCalendar.DAY_OF_MONTH == 12) {
    // Unreachable
}

Já resolvi.
Tinha que dar gCalendar.get(GregorianCalendar.DAY_OF_MONTH) == 12) etc

PEssoal, fui implementar o lance das datas e deu certo em parte, pois consigo dizer que quero listar as proximas N terças-feiras sem problemas.

Mas quando tento, por exemplo, setar os proximos 12 meses, onde a data inicial é “31/03/2012” não consigo achar onde estou errando…

Olhem o código:

public static void main(String[] args) {
		
		int dia, mes, ano, diaInicial = 0;
		
		dia = 31;
		mes = 3;
		ano = 2012;
		
		String data = dia + "/" + mes + "/" + ano;
		
		Date d1 = null;
		
		try {
			d1 = new SimpleDateFormat("dd/MM/yyyy").parse(data);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// Adiciona mes
		Date d2 = addDate(Calendar.MONTH, 1, d1);
		System.out.println("Data orig: " + d1);
		System.out.println("Data +1 mes: " + d2);
		
		System.out.println("");

		// Adiciona dias
		d2 = addDate(Calendar.DAY_OF_MONTH, 30, d1);
		System.out.println("Data orig: " + d1);
		System.out.println("Data +30 dias: " + d2);

		System.out.println("");
		
		// Adiciona Semana
		d2 = addDate(Calendar.WEEK_OF_MONTH, 2, d1);
		System.out.println("Data orig: " + d1);
		System.out.println("Data +2 semana: " + d2);
		
		System.out.println("");
		
		// Adiciona N meses
		for ( int i=1; i<12; i++ ){
			System.out.println("-------------------------------");
			
			Date d3 = addDate(Calendar.MONTH, 1, d1);
			System.out.println("Data +1 mes: " + d3);
			
			d1 = d3;
			
			System.out.println("");
		}
		

	}
	
	public static Date addDate(int field, int amount, Date origDate)
	{
		GregorianCalendar gcal = new GregorianCalendar();
		
		try
		{
			gcal.setTime(origDate);
			gcal.add(field, amount);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
		return ( new Date(gcal.getTime().getTime()) );
	}

Isso imprime o seguinte:

Data orig: Sat Mar 31 00:00:00 BRT 2012
Data +1 mes: Mon Apr 30 00:00:00 BRT 2012

Data orig: Sat Mar 31 00:00:00 BRT 2012
Data +30 dias: Mon Apr 30 00:00:00 BRT 2012

Data orig: Sat Mar 31 00:00:00 BRT 2012
Data +2 semana: Sat Apr 14 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Mon Apr 30 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Fri Jun 01 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Wed Aug 01 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Sun Sep 30 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Thu Nov 01 00:00:00 BRST 2012

-------------------------------
Data +1 mes: Tue Jan 01 00:00:00 BRST 2013

-------------------------------
Data +1 mes: Thu Feb 28 00:00:00 BRT 2013

-------------------------------
Data +1 mes: Wed Apr 03 00:00:00 BRT 2013

-------------------------------
Data +1 mes: Sat Jun 01 00:00:00 BRT 2013

-------------------------------
Data +1 mes: Thu Aug 01 00:00:00 BRT 2013

-------------------------------
Data +1 mes: Mon Sep 30 00:00:00 BRT 2013

Alguem ajuda, por favor?

na verdade o codigo acima imprime isto:

Data orig: Sat Mar 31 00:00:00 BRT 2012
Data +1 mes: Mon Apr 30 00:00:00 BRT 2012

Data orig: Sat Mar 31 00:00:00 BRT 2012
Data +30 dias: Mon Apr 30 00:00:00 BRT 2012

Data orig: Sat Mar 31 00:00:00 BRT 2012
Data +2 semana: Sat Apr 14 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Mon Apr 30 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Wed May 30 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Sat Jun 30 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Mon Jul 30 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Thu Aug 30 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Sun Sep 30 00:00:00 BRT 2012

-------------------------------
Data +1 mes: Tue Oct 30 00:00:00 BRST 2012

-------------------------------
Data +1 mes: Fri Nov 30 00:00:00 BRST 2012

-------------------------------
Data +1 mes: Sun Dec 30 00:00:00 BRST 2012

-------------------------------
Data +1 mes: Wed Jan 30 00:00:00 BRST 2013

-------------------------------
Data +1 mes: Thu Feb 28 00:00:00 BRT 2013

[quote=cerli]na verdade o codigo acima imprime isto:

[code]
Data orig: Sat Mar 31 00:00:00 BRT 2012
Data +1 mes: Mon Apr 30 00:00:00 BRT 2012

Data orig: Sat Mar 31 00:00:00 BRT 2012
Data +30 dias: Mon Apr 30 00:00:00 BRT 2012

Data orig: Sat Mar 31 00:00:00 BRT 2012
Data +2 semana: Sat Apr 14 00:00:00 BRT 2012


Data +1 mes: Mon Apr 30 00:00:00 BRT 2012


Data +1 mes: Wed May 30 00:00:00 BRT 2012


Data +1 mes: Sat Jun 30 00:00:00 BRT 2012


Data +1 mes: Mon Jul 30 00:00:00 BRT 2012


Data +1 mes: Thu Aug 30 00:00:00 BRT 2012


Data +1 mes: Sun Sep 30 00:00:00 BRT 2012


Data +1 mes: Tue Oct 30 00:00:00 BRST 2012


Data +1 mes: Fri Nov 30 00:00:00 BRST 2012


Data +1 mes: Sun Dec 30 00:00:00 BRST 2012


Data +1 mes: Wed Jan 30 00:00:00 BRST 2013


Data +1 mes: Thu Feb 28 00:00:00 BRT 2013
[/code][/quote]

tem uma pergunta aí ? qual data vc queria ?

02 de Março de 2013 ?

ou queria os últimos dias de cada mês ?

se for, está faltando só dar uma olhada na API

http://docs.oracle.com/javase/6/docs/api/java/util/GregorianCalendar.html#getActualMaximum(int)

Eu quero setar qualquer data inicial, mas a data que realmente esta dando problema e quando esta data é o ultimo dia do mês, em especial o dia 31.

Porque parece que o proprio calendar resolve isso da primeira vez, mas depois os proximos meses que poderiam ser esta data inicial do dia 31 ele ignora… Muito estranho…

para obter o ultimo dia eu já resolvi, mas o problemas é justamente esse, por exemplo eu seto como data inicial o dia 31/03/2012 e quero os proximos 12 lancamentos mensais para esta data.

O algoritmo entao deve testar se o ActualMaximun é menor que este 31, por exemplo, mas na proxima iteração do FOR este 31 deve ser usado novamente.

Em algum ponto estou perdendo o fio da meada…

[quote=cerli]para obter o ultimo dia eu já resolvi, mas o problemas é justamente esse, por exemplo eu seto como data inicial o dia 31/03/2012 e quero os proximos 12 lancamentos mensais para esta data.

O algoritmo entao deve testar se o ActualMaximun é menor que este 31, por exemplo, mas na proxima iteração do FOR este 31 deve ser usado novamente.

Em algum ponto estou perdendo o fio da meada…[/quote]

não precisa, é só mudar o seu for para fazer dessa forma, e vc terá o resultado que está querendo:

		// Adiciona N meses
		for (int i = 1; i < 12; i++)
		{
			System.out.println("-------------------------------");

			Date d3 = addDate(Calendar.MONTH, i, d1);
					
			System.out.println("Data +1 mes: " + d3);

//			d1 = d3;

			System.out.println("");
		}

bingoooo!

Era muito simples e eu tentando complicar.

Muito obrigado aechiara.

Abraço!