Datas intercaladas

Oi Gente…
Estou com uma dúvida em relação as datas.

Eu tenho que fazer uma comparação que me retornem se dois períodos de datas se intercalam.
Exemplo I:
1º Período: 01/01/2008 à 31/01/2008
2º período: 15/01/2008 à 15/02/2008
Nesse caso a resposta seria positiva pois 15/01/2008 está entre 01/01/2008 e 31/01/2008

Exemplo II:
1º Período: 01/01/2008 à 31/01/2008
2º período: 01/02/2008 à 15/02/2008
Nesse caso a resposta seria negativa pois o segundo período inicia-se após o primeiro.

Um vez eu fiz uma consulta no Oracle usando between que funcionava.
Será que existe alguma coisa semelhante para JAVA???

Agradeço e comemoro a volta ao JAVA depois de dois anos programando proceduralmente em PHP :frowning:

Olá, você pode utilizar os métodos after() e before() da classe Calendar.

eh soh uma ideia, mas acredito que pode ser mais simples do que parece…

vc compara a data final do primeiro periodo com a inicial do segundo…

  • compara os anos;
  • se true, compara os meses;
  • se true compara as datas;

soh uma ideia viu…

Pegue a data como um todo! Dê uma estudada na classe Calendar. Não fique manuseando dias, meses e anos separadamente. É um trabalho desnecessário, é só estudar um pouco a API. Abraços.

[quote=santina.mota]Oi Gente…
Estou com uma dúvida em relação as datas.

Eu tenho que fazer uma comparação que me retornem se dois períodos de datas se intercalam.
[/quote]

Vc quer saber se se intersectam. Não é tão simples quanto parece.
Eis uma classe que implementa o conceito de intervalo que pode ser usada para testar intersecção

Ela funciona com qualquer coisa que seja comparável. No caso Date.

public class Interval<T> {

	
	protected T start;
	protected T end;
	protected Comparator<? super T> comparator;


	public final static <V> Interval<V> emptyInterval(){
		return new Interval<V>(new ComparableComparator<V>());
	}

	public final static <V> Interval<V> emptyInterval(Comparator<? super V> comparator){
		return new Interval<V>(comparator);
	}
	

	/**
	 * Creates a Interval from the values of two comparable objects. 
	 * @param start start of the Interval
	 * @param end end of the Interval
	 * @throws IllegalArgumentException if start is not less than end or their are null
	 * @throws ClassCastException if the values are not <code>Comparable</code>.
	 * @return a <code>Interval</code> from <code>start</code> to <code>end</code>
	 */
	public final static <V extends Comparable<V>> Interval<V> between(V start, V end){
		return between(start,end,new ComparableComparator<V>());
	} 

	/**
	 * Creates a Interval from the values of two objects and a <code>Comparator</code> for those objects.
	 * @param <V>
	 * @param start start of the Interval
	 * @param end end of the Interval
	 * @param comparator <code>Comparator</code> encapsulating the rules of order for the passed object class
	 * @return a <code>Interval</code> from <code>start</code> to <code>end</code>
	 */
	public static <V> Interval<V> between(V start, V end, Comparator<? super V> comparator){
		if (comparator == null){
			throw new NullPointerException("A comparator is required.");
		}
		if (comparator.compare(start,end)>0){
			throw new IllegalArgumentException("Interval`s start must preceed its end");
		}

		return new Interval<V>(start,end,comparator);
	} 
	

    Interval(T start, T end,Comparator<? super T> comparator) {
		
		this.start = start;
		this.end = end;
		this.comparator = comparator;
	}

	/**
	 * @param start
	 * @param end
	 * @param comparator
	 */
   protected Interval(Comparator<? super T> comparator) {
		this.start = null;
		this.end = null;
		this.comparator = comparator;
	}


	/**
	 * @return Returns the end.
	 */
	public T end() {
		return end;
	}

	/**
	 * @return Returns the start.
	 */
	public T start() {
		return start;
	}

	/**
	 * The interval is empty if the start and end point are equal
	 * @return <code>true</code> if the interval is empty.
	 */
	public boolean isEmpty(){
		// first comparison is necessary as start and end can be null
		return start == end || start.equals(end);
	}



	/**
	 * Determines if this interval intersects another
	 * @param other the candidate to intersection
	 * @return <code>true</code> if <code>this</code> intersects <code>other</code>
	 */
	public boolean intersects (Interval<T> other){

		return !this.isEmpty() && !other.isEmpty() &&
		(this.contains(other.start, true, true) || 
				this.contains(other.end, true, true) || 
				other.contains(this.start, true, true) || 
				other.contains(this.end, true, true));


	}

	/**
	 * Determines this interval intersection with another
	 * @param other the interval to intersect
	 * @return an interval representing the intersections of the intervals
	 */
	public Interval<T> intersection (Interval<T> other){

		// is one is empty the intersection is empty
		if (this.isEmpty() || other.isEmpty()) {
			return new Interval<T>(this.comparator);
		}

		if (other.equals(this)){ // are the same. 
			return other;
		}

		if (this.intersects(other)) {
			// intersects
			return new Interval<T>( max(this.start, other.start), min(this.end, other.end) , comparator);
		} else {
			// does not intersect
			return new Interval<T>(this.comparator);
		}


	}

	/**
	 * The union of this Interval with an another. 
	 * The result is a Interval from the lowest start to the greatest end
	 * Note that union is a commutative operation,
	 * meaning that R.union(S).equals(S.union(R)) == true , R and S being instances of Interval.
	 * @param other
	 * @return a Interval from the lowest start to the greatest end. Example : [2,3] merged with [7,10]  will return [2,10] 
	 */
	public Interval<T> union (Interval<T> other){
		return new Interval<T> ( 
				min(this.start, other.start) , // start at the minor start
				max(this.end , other.end), // end at the major end
				this.comparator // the same comparator
		);
	}


	/**
	 * Determines if an object is between the start(inclusive) and end(inclusive) of the interval
	 * @param other the candidate object
	 * @return <code>true</code> if the object is in the interval , <code>false</code> otherwise
	 */
	public boolean contains(T value){
		return !this.isEmpty() && comparator.compare(value, start) >=0 && comparator.compare(value, end) <=0;
	}


	/**
	 * Determine if the value is contained in the Interval considering the start and the end 
	 * of the Interval as belonging, or not , to the Interval according with openLeft and openRight arguments
	 * @param value the value to test
	 * @param openStart if <code>true<code> test assuming the start of the interval does not belongs to the Interval.
	 * @param openEnd if <code>true<code> test assuming the end of the interval does not belongs to the Interval.
	 * @return
	 */
	public boolean contains(T value, boolean openStart , boolean openEnd){
		//return !this.isEmpty() && (openStart?comparator.compare(value, start) >0: comparator.compare(value, start) >=0 ) && 
		//(openEnd?comparator.compare(value, end) <0:comparator.compare(value, end) <=0);

		return !this.isEmpty() && comparator.compare(value, start) >=0 && comparator.compare(value, end) <=0;
	}


	/**
	 * Determines the maximum of two values using the 
	 * comparator
	 * @param a
	 * @param b
	 * @return the maximum between a and b
	 */
	protected T  max(T a , T b){
		if (comparator.compare(a,b)>=0){
			return a;
		}
		return b;
	}

	/**
	 * Determines the minimum of two values using the 
	 * comparator
	 * @param a
	 * @param b
	 * @return the minimum between a and b
	 */
	protected T  min(T a , T b){
		if (comparator.compare(a,b)<=0){
			return a;
		}
		return b;
	}

	public String toString(){
		if (this.isEmpty()){
			return "[]";
		}
		return "[" + start.toString() + " ; " +  end.toString() + "]";
	}


	/**
	 * Intervals are equal if the their starts are equal and their ends are equals
	 */
	@SuppressWarnings("unchecked")
	public boolean equals(Object other){
		return other instanceof Interval && this.equals((Interval)other);
	}

	/**
	 * Intervals are equal if their starts are equal and their ends are equals
	 */
	public boolean equals(Interval<T> other){
		return (this.isEmpty() && other.isEmpty() ) || // both are empty or the limits are equal
		( comparator.compare(start, other.start)==0 && comparator.compare(end, other.end)==0);
	}

}

Sérgio, você não é acha que é muito código somente para verificar se a menor data consta em um intervalo pré-determinado?
Acho que não precisa de um algoritmo tão genérico e grande. :smiley:

[quote=mfjeng]Sérgio, você não é acha que é muito código somente para verificar se a menor data consta em um intervalo pré-determinado?
Acho que não precisa de um algoritmo tão genérico e grande. :smiley: [/quote]

Eu não acho nada. O problema não se resolve apenas usando Calendar , liás nada tem a haver com Calendar. Nem Date já agora. A classe é grande de mais ? é muito código ? Classes medem-se por metro agora ?
Se é muito grande corta as partes que não quer. O que interessa é que o algoritmo ( que são duas linhas ) só funciona ( em duas linhas) com uma estrutura do tipo intervalo.

Não se reparou para

é um intervalo.

A classe pertence a um projeto meu e acho que é muito mais útil colocá-la toda já que já está pronta.
Mas sinta-se à vontade de cortar o que não lhe interessa, ou usar date/calendar a frio. Afinal, java é uma linguagem OO. Para quÊ vamos querer criar um classe , né ? :roll:

Não tem nada a ver com Calendar? tá certo então.
Desculpe-me…

:shock:

[quote=sergiotaborda]
Eu não acho nada. O problema não se resolve apenas usando Calendar , liás nada tem a haver com Calendar. Nem Date já agora. A classe é grande de mais ? é muito código ? Classes medem-se por metro agora ? [/quote]

Tenho certeza que seu algoritmo é eficiente para o seu propósito. Mas querer passar como se fosse um trator pelo que eu disse parece mesquinhez.
Faça em Assembly então já que escrever código a toa em qualquer contexto é o que você prefere. Sugeri algo bem simples para ela trabalhar com as datas, nada mais.
Desculpe-me.

[quote=mfjeng]Não tem nada a ver com Calendar? tá certo então.
Cara, só comentei uma pequena parte cidadão!
[/quote]

Não. Não tem nada a ver com calendar. O mesmo algoritmo pode funcionar para inteiros ou strings.
O ponto é que vc tem dois valores que mantêm um invervalo e tem dois intervalos. É o intervalo que pode ser intersectado com outro e não o dado que o mantém. Por isso o código que postei usa generics e comparator.
O que interessa realmente é que o objeto que dá suporte ao intervalo seja comparável.

Ficar comentando o tamanho de código tb…
Se vc ficou ofendido com o que eu disse deveria ter pensado antes no que vc disse.

Cara, da uma olhada na api JodaTime, bota no google que vem o site. Ela é a base da nova api de datas para o Java que está sendo construida. Bem legal e mais simples de trabalhar do que as apis padrões do JAVA. Acho que vai encontrar o que quer lá. E caso queria usar o hibernate por exemplo, para persistir, ela ja tem implementação para isso.

Alberto

Gostaria de agradecer todas as sugestões citadas nesse tópico.
Consegui resolver, espero que a lógica não esteja confusa. Aqui vai:

Lembrando que:
dataInicio1 e dataFim1 referem-se ao 1o. período
dataInicio2 e dataFim2 referem-se ao 2o. período

if ((dataFim2.compareTo(dataInicio1) >=0 && dataFim2.compareTo(dataFim1)<=0) || (dataInicio2.compareTo(dataInicio1) >=0 && dataInicio2.compareTo(dataFim1)<=0) || (dataInicio2.compareTo(dataInicio1) <= 0 && dataFim2.compareTo(dataFim1) >= 0) || (dataInicio2.compareTo(dataInicio1) >= 0 && dataFim2.compareTo(dataFim1) <= 0)) { //As datas se intercalam return false; }

Abraços… e mais uma vez muito obrigada!