2011-06-25 14 views
0

dateRangeと他の連続した日付を別のリストで比較すると、リストに対して隣接する範囲が比較されます。

2月9日から5月19日までの期間があります。このオブジェクトが返されるこの日付のようなキー値のMapの有効な日付のリストがもう1つあります(Jan 1、Object x)、(Feb 1、Object y)、(March 1、Object z)(April 1、Object

アルゴリズムの必要性は、2月1日から6月19日までの日付範囲をとり、有効日付範囲の隣接日付を取得することです(例:Object U)。

方法は

TreeMapreturnTemporalAdjacentInterval(間隔)

結果(Feb9-March1、オブジェクトY)との隣接間隔でソートツリーマップ(March1-April1、物体Z)(April1-MAY1なければならないであろう、Object a)(May1-May19、Object u)

これはマーチンファウラーの時間的コレクションのようですが、時間的な隣接間隔の検索のほうが多くなります。言語はJava joda-time Intervalは返された間隔の使用を推奨します。

答えて

1

Martin Fowlers temporal objectのインスピレーションを受けたサンプルクラスは、隣接する間隔を返すためのメソッド実装を備えています。

public HashMap<Interval, Object> getAdjacentIntervals(Interval when) 

これは、特定の複雑さを持つアルゴリズムを示しています。より高速なバージョンの入力。単体テストは

import java.util.HashMap; 
import java.util.Iterator; 

import org.joda.money.Money; 
import org.joda.time.DateMidnight; 
import org.joda.time.Days; 
import org.joda.time.Interval; 
import org.junit.Assert; 
import org.junit.Before; 
import org.junit.Test; 

import com.vrntmgr.server.utils.StringUtils; 

public class TemporalCollectionTest { 

TemporalCollection rates; 

@Before 
public void setup() { 
    rates = new TemporalCollection(); 
    rates.put(new DateMidnight(2010, 1, 1).toDateTime(), 
      Money.parse("USD 900")); 
    rates.put(new DateMidnight(2010, 2, 1).toDateTime(), 
      Money.parse("USD 1000")); 
    rates.put(new DateMidnight(2010, 3, 1).toDateTime(), 
      Money.parse("USD 2000")); 
} 

@Test 
public void testTemporalRetreival() { 
    Interval intrvl = new Interval(new DateMidnight(2010, 1, 15), 
      new DateMidnight(2010, 3, 15)); 

    HashMap<Interval, Object> myMap = rates.getAdjacentIntervals(intrvl); 
    // System.out.println(StringUtils.toString(myMap.keySet())); 


    Iterator<Interval> it = myMap.keySet().iterator(); 
    Assert.assertEquals(it.next(),new Interval(new DateMidnight(2010,3,1), new DateMidnight(2010,3,15))); 
    Assert.assertEquals(it.next(),new Interval(new DateMidnight(2010,2,1), new DateMidnight(2010,3,1))); 
    Assert.assertEquals(it.next(),new Interval(new DateMidnight(2010,1,15), new DateMidnight(2010,2,1))); 
} 

@Test 
public void testEndDayAfterRange() { 


    Interval intrvl = new Interval(new DateMidnight(2010,1,15), new DateMidnight(2010, 2, 1)); 

    HashMap<Interval, Object> myMap = rates.getAdjacentIntervals(intrvl); 


    Iterator<Interval> it = myMap.keySet().iterator(); 
    Interval res = it.next(); 
    Assert.assertEquals(res,new Interval(new DateMidnight(2010,1,15), new DateMidnight(2010,2,1))); 

    System.out.println("days are" + Days.daysIn(res)); 

} 


} 
を次のようにユニットテストクラスがある

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.List; 
import java.util.Map; 

import org.joda.time.DateTime; 
import org.joda.time.Duration; 
import org.joda.time.Interval; 

public class TemporalCollection { 

private Map<DateTime, Object> contents = new HashMap<DateTime, Object>(); 

private List<DateTime> _milestoneCache; 

public Object get(DateTime when) { 
    /** returns the value that was effective on the given date */ 
    Iterator<DateTime> it = milestones().iterator(); 
    while (it.hasNext()) { 
     DateTime thisDate = it.next(); 
     if (thisDate.isBefore(when) || thisDate.equals(when)) 
      return contents.get(thisDate); 
    } 
    throw new IllegalArgumentException("no records that early"); 
} 

public HashMap<Interval, Object> getAdjacentIntervals(Interval when) { 
    // start to get the start date object 
    DateTime startDate = when.getStart(); 
    DateTime endDate = when.getEnd(); 
    HashMap<Interval, Object> result = new HashMap<Interval, Object>(); 
    Iterator<DateTime> it = milestones().iterator(); 

    DateTime endDateToCompare = endDate; 
    DateTime startDateToCompare = startDate; 
    while (it.hasNext()) { 
     DateTime thisDate = it.next(); 
     if (thisDate.isBefore(endDateToCompare) 
       || thisDate.equals(endDateToCompare)) { 
      Interval adjacentIntervalPart; 
      if (thisDate.isAfter(startDateToCompare) && !thisDate.equals(endDateToCompare)) { 
       // we have hit upper end of the range 
       // upper end of the adjacent interval is as follows 
       adjacentIntervalPart = new Interval(thisDate, 
         endDateToCompare); 

       result.put(adjacentIntervalPart, contents.get(thisDate)); 

       endDateToCompare = endDateToCompare.minus(new Duration(
         thisDate, endDateToCompare)); 

      } else { 


       // we have reached the last range 
       adjacentIntervalPart = new Interval(startDate, endDateToCompare); 
       result.put(adjacentIntervalPart, contents.get(thisDate)); 

       return result; 
      } 
     } 

    } 
    throw new IllegalArgumentException("no records that early for an Interval"); 

} 

public void put(DateTime at, Object item) { 
    /** the item is valid and effective from the supplied date onwards */ 
    contents.put(at, item); 
    clearMilestoneCache(); 
} 

private List<DateTime> milestones() { 
    /** 
    * a list of all the dates where the value changed, returned in order 
    * latest first 
    */ 
    if (_milestoneCache == null) 
     calculateMilestones(); 
    return _milestoneCache; 
} 

private void calculateMilestones() { 
    _milestoneCache = new ArrayList<DateTime>(contents.size()); 
    _milestoneCache.addAll(contents.keySet()); 
    Collections.sort(_milestoneCache, Collections.reverseOrder()); 
} 

private void clearMilestoneCache() { 
    _milestoneCache = null; 
} 

} 

オブジェクトのテストを表示するには、以下であり、より良い状況を文書化
関連する問題