blob: c93f43314127bef74811c0d0511751a367f807e4 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 1996-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.util;
import java.util.Date;
import java.util.Vector;
/**
* Implementation of DateRule that takes a range.
* @draft ICU 2.8 (retainAll)
* @provisional This API might change or be removed in a future release.
*/
public class RangeDateRule implements DateRule {
/**
* @draft ICU 2.8
* @provisional This API might change or be removed in a future release.
*/
public RangeDateRule() {
}
/**
* @internal
*/
// Range is a package-private class so this should be package-private too, probably
// public RangeDateRule(Range[] ranges)
// {
// for (int i = 0; i < ranges.length; i++) {
// this.ranges.addElement(ranges[i]);
// }
// }
/**
* @draft ICU 2.8
* @provisional This API might change or be removed in a future release.
*/
public void add(DateRule rule) {
add(new Date(Long.MIN_VALUE), rule);
}
/**
* @draft ICU 2.8
* @provisional This API might change or be removed in a future release.
*/
public void add(Date start, DateRule rule) {
// TODO: Insert in the right place
// System.out.println("Add: " + start.toString());
ranges.addElement(new Range(start, rule));
}
//-----------------------------------------------------------------------
/**
* @draft ICU 2.8
* @provisional This API might change or be removed in a future release.
*/
public Date firstAfter(Date start) {
// Find the range that I should look at
int index = startIndex(start);
if (index == ranges.size()) {
index = 0;
}
Date result = null;
Range r = rangeAt(index);
Range e = rangeAt(index+1);
if (r != null && r.rule != null)
{
if (e != null) {
result = r.rule.firstBetween(start, e.start);
} else {
result = r.rule.firstAfter(start);
}
}
return result;
}
/**
* @draft ICU 2.8
* @provisional This API might change or be removed in a future release.
*/
public Date firstBetween(Date start, Date end) {
if (end == null) {
return firstAfter(start);
}
// Find the range that I should look at
int index = startIndex(start);
Date result = null;
Range next = rangeAt(index);
while (result == null && next != null && !next.start.after(end))
{
Range r = next;
next = rangeAt(index+1);
if (r.rule != null) {
Date e = (next != null && !next.start.after(end)) ? next.start
: end;
result = r.rule.firstBetween(start, e);
}
}
return result;
}
/**
* @draft ICU 2.8
* @provisional This API might change or be removed in a future release.
*/
public boolean isOn(Date date) {
Range r = rangeAt(startIndex(date));
return r != null && r.rule != null && r.rule.isOn(date);
}
/**
* Check whether this event occurs at least once between the two
* dates given.
* @draft ICU 2.8
* @provisional This API might change or be removed in a future release.
*/
public boolean isBetween(Date start, Date end) {
return firstBetween(start,end) == null;
}
/*
* find the index of the last range whose start date is before "start"
* returns an index >= ranges.size() if there is none
*/
private int startIndex(Date start) {
int lastIndex = ranges.size();
for (int i = 0; i < ranges.size(); i++) {
Range r = (Range) ranges.elementAt(i);
if (start.before(r.start)) {
break;
}
lastIndex = i;
}
return lastIndex;
}
private Range rangeAt(int index) {
return (index < ranges.size()) ? (Range) ranges.elementAt(index)
: null;
}
Vector ranges = new Vector(2,2);
}
//-----------------------------------------------------------------------
// Privates
//
class Range {
public Range(Date start, DateRule rule) {
this.start = start;
this.rule = rule;
}
public Date start;
public DateRule rule;
}