📄 segmentedtimeline.java
字号:
);
this.workingCalendar.set(
Calendar.MILLISECOND,
this.workingCalendarNoDST.get(Calendar.MILLISECOND)
);
// result = this.workingCalendar.getTimeInMillis();
// preceding code won't work with JDK 1.3
result = this.workingCalendar.getTime().getTime();
}
return result;
}
/**
* Returns <code>true</code> if a value is contained in the timeline.
*
* @param millisecond the value to verify.
*
* @return <code>true</code> if value is contained in the timeline.
*/
public boolean containsDomainValue(long millisecond) {
Segment segment = getSegment(millisecond);
return segment.inIncludeSegments();
}
/**
* Returns <code>true</code> if a value is contained in the timeline.
*
* @param date date to verify
*
* @return <code>true</code> if value is contained in the timeline
*/
public boolean containsDomainValue(Date date) {
return containsDomainValue(getTime(date));
}
/**
* Returns <code>true</code> if a range of values are contained in the
* timeline. This is implemented verifying that all segments are in the
* range.
*
* @param domainValueStart start of the range to verify
* @param domainValueEnd end of the range to verify
*
* @return <code>true</code> if the range is contained in the timeline
*/
public boolean containsDomainRange(long domainValueStart,
long domainValueEnd) {
if (domainValueEnd < domainValueStart) {
throw new IllegalArgumentException(
"domainValueEnd (" + domainValueEnd
+ ") < domainValueStart (" + domainValueStart + ")"
);
}
Segment segment = getSegment(domainValueStart);
boolean contains = true;
do {
contains = (segment.inIncludeSegments());
if (segment.contains(domainValueEnd)) {
break;
}
else {
segment.inc();
}
}
while (contains);
return (contains);
}
/**
* Returns <code>true</code> if a range of values are contained in the
* timeline. This is implemented verifying that all segments are in the
* range.
*
* @param dateDomainValueStart start of the range to verify
* @param dateDomainValueEnd end of the range to verify
*
* @return <code>true</code> if the range is contained in the timeline
*/
public boolean containsDomainRange(Date dateDomainValueStart,
Date dateDomainValueEnd) {
return containsDomainRange(
getTime(dateDomainValueStart), getTime(dateDomainValueEnd)
);
}
/**
* Adds a segment as an exception. An exception segment is defined as a
* segment to exclude from what would otherwise be considered a valid
* segment of the timeline. An exception segment can not be contained
* inside an already excluded segment. If so, no action will occur (the
* proposed exception segment will be discarded).
* <p>
* The segment is identified by a domainValue into any part of the segment.
* Therefore the segmentStart <= domainValue <= segmentEnd.
*
* @param millisecond domain value to treat as an exception
*/
public void addException(long millisecond) {
addException(new Segment(millisecond));
}
/**
* Adds a segment range as an exception. An exception segment is defined as
* a segment to exclude from what would otherwise be considered a valid
* segment of the timeline. An exception segment can not be contained
* inside an already excluded segment. If so, no action will occur (the
* proposed exception segment will be discarded).
* <p>
* The segment range is identified by a domainValue that begins a valid
* segment and ends with a domainValue that ends a valid segment.
* Therefore the range will contain all segments whose segmentStart
* <= domainValue and segmentEnd <= toDomainValue.
*
* @param fromDomainValue start of domain range to treat as an exception
* @param toDomainValue end of domain range to treat as an exception
*/
public void addException(long fromDomainValue, long toDomainValue) {
addException(new SegmentRange(fromDomainValue, toDomainValue));
}
/**
* Adds a segment as an exception. An exception segment is defined as a
* segment to exclude from what would otherwise be considered a valid
* segment of the timeline. An exception segment can not be contained
* inside an already excluded segment. If so, no action will occur (the
* proposed exception segment will be discarded).
* <p>
* The segment is identified by a Date into any part of the segment.
*
* @param exceptionDate Date into the segment to exclude.
*/
public void addException(Date exceptionDate) {
addException(getTime(exceptionDate));
//addException(exceptionDate.getTime());
}
/**
* Adds a list of dates as segment exceptions. Each exception segment is
* defined as a segment to exclude from what would otherwise be considered
* a valid segment of the timeline. An exception segment can not be
* contained inside an already excluded segment. If so, no action will
* occur (the proposed exception segment will be discarded).
* <p>
* The segment is identified by a Date into any part of the segment.
*
* @param exceptionList List of Date objects that identify the segments to
* exclude.
*/
public void addExceptions(List exceptionList) {
for (Iterator iter = exceptionList.iterator(); iter.hasNext();) {
addException((Date) iter.next());
}
}
/**
* Adds a segment as an exception. An exception segment is defined as a
* segment to exclude from what would otherwise be considered a valid
* segment of the timeline. An exception segment can not be contained
* inside an already excluded segment. This is verified inside this
* method, and if so, no action will occur (the proposed exception segment
* will be discarded).
*
* @param segment the segment to exclude.
*/
private void addException(Segment segment) {
if (segment.inIncludeSegments()) {
int p = binarySearchExceptionSegments(segment);
this.exceptionSegments.add(-(p + 1), segment);
}
}
/**
* Adds a segment relative to the baseTimeline as an exception. Because a
* base segment is normally larger than our segments, this may add one or
* more segment ranges to the exception list.
* <p>
* An exception segment is defined as a segment
* to exclude from what would otherwise be considered a valid segment of
* the timeline. An exception segment can not be contained inside an
* already excluded segment. If so, no action will occur (the proposed
* exception segment will be discarded).
* <p>
* The segment is identified by a domainValue into any part of the
* baseTimeline segment.
*
* @param domainValue domain value to teat as a baseTimeline exception.
*/
public void addBaseTimelineException(long domainValue) {
Segment baseSegment = this.baseTimeline.getSegment(domainValue);
if (baseSegment.inIncludeSegments()) {
// cycle through all the segments contained in the BaseTimeline
// exception segment
Segment segment = getSegment(baseSegment.getSegmentStart());
while (segment.getSegmentStart() <= baseSegment.getSegmentEnd()) {
if (segment.inIncludeSegments()) {
// find all consecutive included segments
long fromDomainValue = segment.getSegmentStart();
long toDomainValue;
do {
toDomainValue = segment.getSegmentEnd();
segment.inc();
}
while (segment.inIncludeSegments());
// add the interval as an exception
addException(fromDomainValue, toDomainValue);
}
else {
// this is not one of our included segment, skip it
segment.inc();
}
}
}
}
/**
* Adds a segment relative to the baseTimeline as an exception. An
* exception segment is defined as a segment to exclude from what would
* otherwise be considered a valid segment of the timeline. An exception
* segment can not be contained inside an already excluded segment. If so,
* no action will occure (the proposed exception segment will be discarded).
* <p>
* The segment is identified by a domainValue into any part of the segment.
* Therefore the segmentStart <= domainValue <= segmentEnd.
*
* @param date date domain value to treat as a baseTimeline exception
*/
public void addBaseTimelineException(Date date) {
addBaseTimelineException(getTime(date));
}
/**
* Adds all excluded segments from the BaseTimeline as exceptions to our
* timeline. This allows us to combine two timelines for more complex
* calculations.
*
* @param fromBaseDomainValue Start of the range where exclusions will be
* extracted.
* @param toBaseDomainValue End of the range to process.
*/
public void addBaseTimelineExclusions(long fromBaseDomainValue,
long toBaseDomainValue) {
// find first excluded base segment starting fromDomainValue
Segment baseSegment = this.baseTimeline.getSegment(fromBaseDomainValue);
while (baseSegment.getSegmentStart() <= toBaseDomainValue
&& !baseSegment.inExcludeSegments()) {
baseSegment.inc();
}
// cycle over all the base segments groups in the range
while (baseSegment.getSegmentStart() <= toBaseDomainValue) {
long baseExclusionRangeEnd = baseSegment.getSegmentStart()
+ this.baseTimeline.getSegmentsExcluded()
* this.baseTimeline.getSegmentSize() - 1;
// cycle through all the segments contained in the base exclusion
// area
Segment segment = getSegment(baseSegment.getSegmentStart());
while (segment.getSegmentStart() <= baseExclusionRangeEnd) {
if (segment.inIncludeSegments()) {
// find all consecutive included segments
long fromDomainValue = segment.getSegmentStart();
long toDomainValue;
do {
toDomainValue = segment.getSegmentEnd();
segment.inc();
}
while (segment.inIncludeSegments());
// add the interval as an exception
addException(new BaseTimelineSegmentRange(
fromDomainValue, toDomainValue
));
}
else {
// this is not one of our included segment, skip it
segment.inc();
}
}
// go to next base segment group
baseSegment.inc(this.baseTimeline.getGroupSegmentCount());
}
}
/**
* Returns the number of exception segments wholly contained in the
* (fromDomainValue, toDomainValue) interval.
*
* @param fromMillisecond the beginning of the interval.
* @param toMillisecond the end of the interval.
*
* @return Number of exception segments contained in the interval.
*/
public long getExceptionSegmentCount(long fromMillisecond,
long toMillisecond) {
if (toMillisecond < fromMillisecond) {
return (0);
}
int n = 0;
for (Iterator iter = this.exceptionSegments.iterator();
iter.hasNext();) {
Segment segment = (Segment) iter.next();
Segment intersection
= segment.intersect(fromMillisecond, toMillisecond);
if (intersection != null) {
n += intersection.getSegmentCount();
}
}
return (n);
}
/**
* Returns a segment that contains a domainValue. If the domainValue is
* not contained in the timeline (because it is not contained in the
* baseTimeline), a Segment that contains
* <code>index + segmentSize*m</code> will be returned for the smallest
* <code>m</code> possible.
*
* @param millisecond index into the segment
*
* @return A Segment that contains index, or the next possible Segment.
*/
public Segment getSegment(long millisecond) {
return new Segment(millisecond);
}
/**
* Returns a segment that contains a date. For accurate calculations,
* the calendar should use TIME_ZONE for its calculation (or any other
* similar time zone).
*
* If the date is not contained in the timeline (because it is not
* contained in the baseTimeline), a Segment that contains
* <code>date + segmentSize*m</code> will be returned for the smallest
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -