📄 segmentedtimeline.java
字号:
* <code>m</code> possible.
*
* @param date date into the segment
*
* @return A Segment that contains date, or the next possible Segment.
*/
public Segment getSegment(Date date) {
return (getSegment(getTime(date)));
}
/**
* Convenient method to test equality in two objects, taking into account
* nulls.
*
* @param o first object to compare
* @param p second object to compare
*
* @return <code>true</code> if both objects are equal or both
* <code>null</code>, <code>false</code> otherwise.
*/
private boolean equals(Object o, Object p) {
return (o == p || ((o != null) && o.equals(p)));
}
/**
* Returns true if we are equal to the parameter
*
* @param o Object to verify with us
*
* @return <code>true</code> or <code>false</code>
*/
public boolean equals(Object o) {
if (o instanceof SegmentedTimeline) {
SegmentedTimeline other = (SegmentedTimeline) o;
boolean b0 = (this.segmentSize == other.getSegmentSize());
boolean b1 = (this.segmentsIncluded == other.getSegmentsIncluded());
boolean b2 = (this.segmentsExcluded == other.getSegmentsExcluded());
boolean b3 = (this.startTime == other.getStartTime());
boolean b4 = equals(
this.exceptionSegments, other.getExceptionSegments()
);
return b0 && b1 && b2 && b3 && b4;
}
else {
return (false);
}
}
/**
* Returns a hash code for this object.
*
* @return A hash code.
*/
public int hashCode() {
int result = 19;
result = 37 * result
+ (int) (this.segmentSize ^ (this.segmentSize >>> 32));
result = 37 * result + (int) (this.startTime ^ (this.startTime >>> 32));
return result;
}
/**
* Preforms a binary serach in the exceptionSegments sorted array. This
* array can contain Segments or SegmentRange objects.
*
* @param segment the key to be searched for.
*
* @return index of the search segment, if it is contained in the list;
* otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
* <i>insertion point</i> is defined as the point at which the
* segment would be inserted into the list: the index of the first
* element greater than the key, or <tt>list.size()</tt>, if all
* elements in the list are less than the specified segment. Note
* that this guarantees that the return value will be >= 0 if
* and only if the key is found.
*/
private int binarySearchExceptionSegments(Segment segment) {
int low = 0;
int high = this.exceptionSegments.size() - 1;
while (low <= high) {
int mid = (low + high) / 2;
Segment midSegment = (Segment) this.exceptionSegments.get(mid);
// first test for equality (contains or contained)
if (segment.contains(midSegment) || midSegment.contains(segment)) {
return mid;
}
if (midSegment.before(segment)) {
low = mid + 1;
}
else if (midSegment.after(segment)) {
high = mid - 1;
}
else {
throw new IllegalStateException("Invalid condition.");
}
}
return -(low + 1); // key not found
}
/**
* Special method that handles conversion between the Default Time Zone and
* a UTC time zone with no DST. This is needed so all days have the same
* size. This method is the prefered way of converting a Data into
* milliseconds for usage in this class.
*
* @param date Date to convert to long.
*
* @return The milliseconds.
*/
public long getTime(Date date) {
long result = date.getTime();
if (this.adjustForDaylightSaving) {
this.workingCalendar.setTime(date);
this.workingCalendarNoDST.set(
this.workingCalendar.get(Calendar.YEAR),
this.workingCalendar.get(Calendar.MONTH),
this.workingCalendar.get(Calendar.DATE),
this.workingCalendar.get(Calendar.HOUR_OF_DAY),
this.workingCalendar.get(Calendar.MINUTE),
this.workingCalendar.get(Calendar.SECOND)
);
this.workingCalendarNoDST.set(
Calendar.MILLISECOND,
this.workingCalendar.get(Calendar.MILLISECOND)
);
Date revisedDate = this.workingCalendarNoDST.getTime();
result = revisedDate.getTime();
}
return result;
}
/**
* Converts a millisecond value into a {@link Date} object.
*
* @param value the millisecond value.
*
* @return The date.
*/
public Date getDate(long value) {
this.workingCalendarNoDST.setTime(new Date(value));
return (this.workingCalendarNoDST.getTime());
}
/**
* Returns a clone of the timeline.
*
* @return A clone.
*
* @throws CloneNotSupportedException ??.
*/
public Object clone() throws CloneNotSupportedException {
SegmentedTimeline clone = (SegmentedTimeline) super.clone();
return clone;
}
/**
* Internal class to represent a valid segment for this timeline. A segment
* is valid on a timeline if it is part of its included, excluded or
* exception segments.
* <p>
* Each segment will know its segment number, segmentStart, segmentEnd and
* index inside the segment.
*/
public class Segment implements Comparable, Cloneable, Serializable {
/** The segment number. */
protected long segmentNumber;
/** The segment start. */
protected long segmentStart;
/** The segment end. */
protected long segmentEnd;
/** A reference point within the segment. */
protected long millisecond;
/**
* Protected constructor only used by sub-classes.
*/
protected Segment() {
// empty
}
/**
* Creates a segment for a given point in time.
*
* @param millisecond the millisecond (as encoded by java.util.Date).
*/
protected Segment(long millisecond) {
this.segmentNumber = calculateSegmentNumber(millisecond);
this.segmentStart = SegmentedTimeline.this.startTime
+ this.segmentNumber * SegmentedTimeline.this.segmentSize;
this.segmentEnd
= this.segmentStart + SegmentedTimeline.this.segmentSize - 1;
this.millisecond = millisecond;
}
/**
* Calculates the segment number for a given millisecond.
*
* @param millis the millisecond (as encoded by java.util.Date).
*
* @return The segment number.
*/
public long calculateSegmentNumber(long millis) {
if (millis >= SegmentedTimeline.this.startTime) {
return (millis - SegmentedTimeline.this.startTime)
/ SegmentedTimeline.this.segmentSize;
}
else {
return ((millis - SegmentedTimeline.this.startTime)
/ SegmentedTimeline.this.segmentSize) - 1;
}
}
/**
* Returns the segment number of this segment. Segments start at 0.
*
* @return The segment number.
*/
public long getSegmentNumber() {
return this.segmentNumber;
}
/**
* Returns always one (the number of segments contained in this
* segment).
*
* @return The segment count (always 1 for this class).
*/
public long getSegmentCount() {
return 1;
}
/**
* Gets the start of this segment in ms.
*
* @return The segment start.
*/
public long getSegmentStart() {
return this.segmentStart;
}
/**
* Gets the end of this segment in ms.
*
* @return The segment end.
*/
public long getSegmentEnd() {
return this.segmentEnd;
}
/**
* Returns the millisecond used to reference this segment (always
* between the segmentStart and segmentEnd).
*
* @return The millisecond.
*/
public long getMillisecond() {
return this.millisecond;
}
/**
* Returns a {@link java.util.Date} that represents the reference point
* for this segment.
*
* @return The date.
*/
public Date getDate() {
return SegmentedTimeline.this.getDate(this.millisecond);
}
/**
* Returns true if a particular millisecond is contained in this
* segment.
*
* @param millis the millisecond to verify.
*
* @return <code>true</code> if the millisecond is contained in the
* segment.
*/
public boolean contains(long millis) {
return (this.segmentStart <= millis && millis <= this.segmentEnd);
}
/**
* Returns <code>true</code> if an interval is contained in this
* segment.
*
* @param from the start of the interval.
* @param to the end of the interval.
*
* @return <code>true</code> if the interval is contained in the
* segment.
*/
public boolean contains(long from, long to) {
return (this.segmentStart <= from && to <= this.segmentEnd);
}
/**
* Returns <code>true</code> if a segment is contained in this segment.
*
* @param segment the segment to test for inclusion
*
* @return <code>true</code> if the segment is contained in this
* segment.
*/
public boolean contains(Segment segment) {
return contains(segment.getSegmentStart(), segment.getSegmentEnd());
}
/**
* Returns <code>true</code> if this segment is contained in an
* interval.
*
* @param from the start of the interval.
* @param to the end of the interval.
*
* @return <code>true</code> if this segment is contained in the
* interval.
*/
public boolean contained(long from, long to) {
return (from <= this.segmentStart && this.segmentEnd <= to);
}
/**
* Returns a segment that is the intersection of this segment and the
* interval.
*
* @param from the start of the interval.
* @param to the end of the interval.
*
* @return A segment.
*/
public Segment intersect(long from, long to) {
if (from <= this.segmentStart && this.segmentEnd <= to) {
return this;
}
else {
return null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -