All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.joda.time.base.AbstractInterval Maven / Gradle / Ivy

The newest version!
/*
 *  Copyright 2001-2011 Stephen Colebourne
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.joda.time.base;

import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils;
import org.joda.time.Duration;
import org.joda.time.Interval;
import org.joda.time.MutableInterval;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.joda.time.ReadableInstant;
import org.joda.time.ReadableInterval;
import org.joda.time.field.FieldUtils;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

/**
 * AbstractInterval provides the common behaviour for time intervals.
 * 

* This class should generally not be used directly by API users. The * {@link ReadableInterval} interface should be used when different * kinds of intervals are to be referenced. *

* AbstractInterval subclasses may be mutable and not thread-safe. * * @author Brian S O'Neill * @author Stephen Colebourne * @since 1.0 */ public abstract class AbstractInterval implements ReadableInterval { /** * Constructor. */ protected AbstractInterval() { super(); } //----------------------------------------------------------------------- /** * Validates an interval. * * @param start the start instant in milliseconds * @param end the end instant in milliseconds * @throws IllegalArgumentException if the interval is invalid */ protected void checkInterval(long start, long end) { if (end < start) { throw new IllegalArgumentException("The end instant must be greater or equal to the start"); } } //----------------------------------------------------------------------- /** * Gets the start of this time interval, which is inclusive, as a DateTime. * * @return the start of the time interval */ public DateTime getStart() { return new DateTime(getStartMillis(), getChronology()); } /** * Gets the end of this time interval, which is exclusive, as a DateTime. * * @return the end of the time interval */ public DateTime getEnd() { return new DateTime(getEndMillis(), getChronology()); } //----------------------------------------------------------------------- /** * Does this time interval contain the specified millisecond instant. *

* Non-zero duration intervals are inclusive of the start instant and * exclusive of the end. A zero duration interval cannot contain anything. * * @param millisInstant the instant to compare to, * millisecond instant from 1970-01-01T00:00:00Z * @return true if this time interval contains the millisecond */ public boolean contains(long millisInstant) { long thisStart = getStartMillis(); long thisEnd = getEndMillis(); return (millisInstant >= thisStart && millisInstant < thisEnd); } /** * Does this time interval contain the current instant. *

* Non-zero duration intervals are inclusive of the start instant and * exclusive of the end. A zero duration interval cannot contain anything. * * @return true if this time interval contains the current instant */ public boolean containsNow() { return contains(DateTimeUtils.currentTimeMillis()); } /** * Does this time interval contain the specified instant. *

* Non-zero duration intervals are inclusive of the start instant and * exclusive of the end. A zero duration interval cannot contain anything. *

* For example: *

     * [09:00 to 10:00) contains 08:59  = false (before start)
     * [09:00 to 10:00) contains 09:00  = true
     * [09:00 to 10:00) contains 09:59  = true
     * [09:00 to 10:00) contains 10:00  = false (equals end)
     * [09:00 to 10:00) contains 10:01  = false (after end)
     * 
     * [14:00 to 14:00) contains 14:00  = false (zero duration contains nothing)
     * 
* Passing in a null parameter will have the same effect as * calling {@link #containsNow()}. * * @param instant the instant, null means now * @return true if this time interval contains the instant */ public boolean contains(ReadableInstant instant) { if (instant == null) { return containsNow(); } return contains(instant.getMillis()); } /** * Does this time interval contain the specified time interval. *

* Non-zero duration intervals are inclusive of the start instant and * exclusive of the end. The other interval is contained if this interval * wholly contains, starts, finishes or equals it. * A zero duration interval cannot contain anything. *

* When two intervals are compared the result is one of three states: * (a) they abut, (b) there is a gap between them, (c) they overlap. * The contains method is not related to these states. * In particular, a zero duration interval is contained at the start of * a larger interval, but does not overlap (it abuts instead). *

* For example: *

     * [09:00 to 10:00) contains [09:00 to 10:00)  = true
     * [09:00 to 10:00) contains [09:00 to 09:30)  = true
     * [09:00 to 10:00) contains [09:30 to 10:00)  = true
     * [09:00 to 10:00) contains [09:15 to 09:45)  = true
     * [09:00 to 10:00) contains [09:00 to 09:00)  = true
     * 
     * [09:00 to 10:00) contains [08:59 to 10:00)  = false (otherStart before thisStart)
     * [09:00 to 10:00) contains [09:00 to 10:01)  = false (otherEnd after thisEnd)
     * [09:00 to 10:00) contains [10:00 to 10:00)  = false (otherStart equals thisEnd)
     * 
     * [14:00 to 14:00) contains [14:00 to 14:00)  = false (zero duration contains nothing)
     * 
* Passing in a null parameter will have the same effect as * calling {@link #containsNow()}. * * @param interval the time interval to compare to, null means a zero duration interval now * @return true if this time interval contains the time interval */ public boolean contains(ReadableInterval interval) { if (interval == null) { return containsNow(); } long otherStart = interval.getStartMillis(); long otherEnd = interval.getEndMillis(); long thisStart = getStartMillis(); long thisEnd = getEndMillis(); return (thisStart <= otherStart && otherStart < thisEnd && otherEnd <= thisEnd); } /** * Does this time interval overlap the specified time interval. *

* Intervals are inclusive of the start instant and exclusive of the end. * An interval overlaps another if it shares some common part of the * datetime continuum. *

* When two intervals are compared the result is one of three states: * (a) they abut, (b) there is a gap between them, (c) they overlap. * The abuts state takes precedence over the other two, thus a zero duration * interval at the start of a larger interval abuts and does not overlap. *

* For example: *

     * [09:00 to 10:00) overlaps [08:00 to 08:30)  = false (completely before)
     * [09:00 to 10:00) overlaps [08:00 to 09:00)  = false (abuts before)
     * [09:00 to 10:00) overlaps [08:00 to 09:30)  = true
     * [09:00 to 10:00) overlaps [08:00 to 10:00)  = true
     * [09:00 to 10:00) overlaps [08:00 to 11:00)  = true
     * 
     * [09:00 to 10:00) overlaps [09:00 to 09:00)  = false (abuts before)
     * [09:00 to 10:00) overlaps [09:00 to 09:30)  = true
     * [09:00 to 10:00) overlaps [09:00 to 10:00)  = true
     * [09:00 to 10:00) overlaps [09:00 to 11:00)  = true
     * 
     * [09:00 to 10:00) overlaps [09:30 to 09:30)  = true
     * [09:00 to 10:00) overlaps [09:30 to 10:00)  = true
     * [09:00 to 10:00) overlaps [09:30 to 11:00)  = true
     * 
     * [09:00 to 10:00) overlaps [10:00 to 10:00)  = false (abuts after)
     * [09:00 to 10:00) overlaps [10:00 to 11:00)  = false (abuts after)
     * 
     * [09:00 to 10:00) overlaps [10:30 to 11:00)  = false (completely after)
     * 
     * [14:00 to 14:00) overlaps [14:00 to 14:00)  = false (abuts before and after)
     * [14:00 to 14:00) overlaps [13:00 to 15:00)  = true
     * 
* * @param interval the time interval to compare to, null means a zero length interval now * @return true if the time intervals overlap */ public boolean overlaps(ReadableInterval interval) { long thisStart = getStartMillis(); long thisEnd = getEndMillis(); if (interval == null) { long now = DateTimeUtils.currentTimeMillis(); return (thisStart < now && now < thisEnd); } else { long otherStart = interval.getStartMillis(); long otherEnd = interval.getEndMillis(); return (thisStart < otherEnd && otherStart < thisEnd); } } //----------------------------------------------------------------------- /** * Is this time interval before the specified millisecond instant. *

* Intervals are inclusive of the start instant and exclusive of the end. * * @param millisInstant the instant to compare to, * millisecond instant from 1970-01-01T00:00:00Z * @return true if this time interval is before the instant */ public boolean isBefore(long millisInstant) { return (getEndMillis() <= millisInstant); } /** * Is this time interval before the current instant. *

* Intervals are inclusive of the start instant and exclusive of the end. * * @return true if this time interval is before the current instant */ public boolean isBeforeNow() { return isBefore(DateTimeUtils.currentTimeMillis()); } /** * Is this time interval before the specified instant. *

* Intervals are inclusive of the start instant and exclusive of the end. * * @param instant the instant to compare to, null means now * @return true if this time interval is before the instant */ public boolean isBefore(ReadableInstant instant) { if (instant == null) { return isBeforeNow(); } return isBefore(instant.getMillis()); } /** * Is this time interval entirely before the specified instant. *

* Intervals are inclusive of the start instant and exclusive of the end. * * @param interval the interval to compare to, null means now * @return true if this time interval is before the interval specified */ public boolean isBefore(ReadableInterval interval) { if (interval == null) { return isBeforeNow(); } return isBefore(interval.getStartMillis()); } //----------------------------------------------------------------------- /** * Is this time interval after the specified millisecond instant. *

* Intervals are inclusive of the start instant and exclusive of the end. * * @param millisInstant the instant to compare to, * millisecond instant from 1970-01-01T00:00:00Z * @return true if this time interval is after the instant */ public boolean isAfter(long millisInstant) { return (getStartMillis() > millisInstant); } /** * Is this time interval after the current instant. *

* Intervals are inclusive of the start instant and exclusive of the end. * * @return true if this time interval is after the current instant */ public boolean isAfterNow() { return isAfter(DateTimeUtils.currentTimeMillis()); } /** * Is this time interval after the specified instant. *

* Intervals are inclusive of the start instant and exclusive of the end. * * @param instant the instant to compare to, null means now * @return true if this time interval is after the instant */ public boolean isAfter(ReadableInstant instant) { if (instant == null) { return isAfterNow(); } return isAfter(instant.getMillis()); } /** * Is this time interval entirely after the specified interval. *

* Intervals are inclusive of the start instant and exclusive of the end. * Only the end time of the specified interval is used in the comparison. * * @param interval the interval to compare to, null means now * @return true if this time interval is after the interval specified */ public boolean isAfter(ReadableInterval interval) { long endMillis; if (interval == null) { endMillis = DateTimeUtils.currentTimeMillis(); } else { endMillis = interval.getEndMillis(); } return (getStartMillis() >= endMillis); } //----------------------------------------------------------------------- /** * Get this interval as an immutable Interval object. * * @return the interval as an Interval object */ public Interval toInterval() { return new Interval(getStartMillis(), getEndMillis(), getChronology()); } /** * Get this time interval as a MutableInterval. *

* This will always return a new MutableInterval with the same interval. * * @return the time interval as a MutableInterval object */ public MutableInterval toMutableInterval() { return new MutableInterval(getStartMillis(), getEndMillis(), getChronology()); } //----------------------------------------------------------------------- /** * Gets the duration of this time interval in milliseconds. *

* The duration is equal to the end millis minus the start millis. * * @return the duration of the time interval in milliseconds * @throws ArithmeticException if the duration exceeds the capacity of a long */ public long toDurationMillis() { return FieldUtils.safeAdd(getEndMillis(), -getStartMillis()); } /** * Gets the duration of this time interval. *

* The duration is equal to the end millis minus the start millis. * * @return the duration of the time interval * @throws ArithmeticException if the duration exceeds the capacity of a long */ public Duration toDuration() { long durMillis = toDurationMillis(); if (durMillis == 0) { return Duration.ZERO; } else { return new Duration(durMillis); } } //----------------------------------------------------------------------- /** * Converts the duration of the interval to a Period using the * All period type. *

* This method should be used to exract the field values describing the * difference between the start and end instants. * * @return a time period derived from the interval */ public Period toPeriod() { return new Period(getStartMillis(), getEndMillis(), getChronology()); } /** * Converts the duration of the interval to a Period using the * specified period type. *

* This method should be used to exract the field values describing the * difference between the start and end instants. * * @param type the requested type of the duration, null means AllType * @return a time period derived from the interval */ public Period toPeriod(PeriodType type) { return new Period(getStartMillis(), getEndMillis(), type, getChronology()); } //----------------------------------------------------------------------- /** * Compares this object with the specified object for equality based * on start and end millis plus the chronology. * All ReadableInterval instances are accepted. *

* To compare the duration of two time intervals, use {@link #toDuration()} * to get the durations and compare those. * * @param readableInterval a readable interval to check against * @return true if the start and end millis are equal */ public boolean equals(Object readableInterval) { if (this == readableInterval) { return true; } if (readableInterval instanceof ReadableInterval == false) { return false; } ReadableInterval other = (ReadableInterval) readableInterval; return getStartMillis() == other.getStartMillis() && getEndMillis() == other.getEndMillis() && FieldUtils.equals(getChronology(), other.getChronology()); } /** * Hashcode compatible with equals method. * * @return suitable hashcode */ public int hashCode() { long start = getStartMillis(); long end = getEndMillis(); int result = 97; result = 31 * result + ((int) (start ^ (start >>> 32))); result = 31 * result + ((int) (end ^ (end >>> 32))); result = 31 * result + getChronology().hashCode(); return result; } /** * Output a string in ISO8601 interval format. *

* From version 2.1, the string includes the time zone offset. * * @return re-parsable string (in the default zone) */ public String toString() { DateTimeFormatter printer = ISODateTimeFormat.dateTime(); printer = printer.withChronology(getChronology()); StringBuffer buf = new StringBuffer(48); printer.printTo(buf, getStartMillis()); buf.append('/'); printer.printTo(buf, getEndMillis()); return buf.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy