001/*
002 * $Id: DateSpan.java 542 2005-10-10 18:03:15Z rbair $
003 *
004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 * 
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015 * Lesser General Public License for more details.
016 * 
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020 */
021package org.jdesktop.swingx.calendar;
022
023import java.util.Date;
024
025/**
026 * An immutable representation of a time range.  The time range is
027 * internally represented as two longs. The methods that take and return
028 * <code>Date</code>s create the <code>Date</code>s as needed, so that
029 * if you modify returned <code>Date</code>s you will <b>not</b> effect
030 * the <code>DateSpan</code>.  The end points are inclusive.
031 *
032 * @version  $Revision: 542 $
033 */
034public class DateSpan {
035    private long _start;
036    private long _end;
037
038    /**
039     * Creates a <code>DateSpan</code> between the two end points.
040     *
041     * @param start Beginning date
042     * @param end Ending date
043     * @throws IllegalArgumentException if <code>start</code> is after
044     *         <code>end</code>
045     */
046    public DateSpan(long start, long end) {
047        _start = start;
048        _end = end;
049        if (_start > _end) {
050            throw new IllegalArgumentException(
051                             "Start date must be before end date");
052        }
053    }
054
055    /**
056     * Creates a <code>DateSpan</code> between the two end points.  This
057     * is a conveniance constructor that is equivalent to
058     * <code>new Date(start.getTime(), end.getTime());</code>.
059     *
060     * @param start Beginning date
061     * @param end Ending date
062     */
063    public DateSpan(Date start, Date end) {
064        this(start.getTime(), end.getTime());
065    }
066
067    /**
068     * Returns the start of the date span.
069     *
070     * @return start of the  span.
071     */
072    public long getStart() {
073        return _start;
074    }
075
076    /**
077     * Returns the end of the date span.
078     *
079     * @return end of the span.
080     */
081    public long getEnd() {
082        return _end;
083    }
084
085    /**
086     * Returns the start of the date span as a <code>Date</code>.
087     *
088     * @return start of the  span.
089     */
090    public Date getStartAsDate() {
091        return new Date(getStart());
092    }
093
094    /**
095     * Returns the end of the date span as a <code>Date</code>.
096     *
097     * @return end of the span.
098     */
099    public Date getEndAsDate() {
100        return new Date(getEnd());
101    }
102
103    /**
104     * Returns true if this <code>DateSpan</code> contains the specified
105     * <code>DateSpan</code>.
106     *
107     * @param span Date to check
108     * @return true if this DateSpan contains <code>span</code>.
109     */
110    public boolean contains(DateSpan span) {
111        return (contains(span.getStart()) && contains(span.getEnd()));
112    }
113
114    /**
115     * Returns whether or not this <code>DateSpan</code> contains the specified
116     * time.
117     *
118     * @param time time check
119     * @return true if this DateSpan contains <code>time</code>.
120     */
121    public boolean contains(long time) {
122        return (time >= getStart() && time <= getEnd());
123    }
124
125    /**
126     * Returns whether or not this <code>DateSpan</code> contains the
127     * specified date span.
128     *
129     * @param start Start of time span
130     * @param end End of time
131     * @return true if this <code>DateSpan</code> contains the specified
132     *         date span.
133     */
134    public boolean contains(long start, long end) {
135        return (start >= getStart() && end <= getEnd());
136    }
137
138    /**
139     * Returns true if the this <code>DateSpan</code> intersects with the
140     * specified time.
141     *
142     * @param start Start time
143     * @param end End time
144     * @return true if this <code>DateSpan</code> intersects with the specified
145     * time.
146     */
147    public boolean intersects(long start, long end) {
148        return (start <= getEnd() && end >= getStart());
149    }
150
151    /**
152     * Returns true if the this <code>DateSpan</code> intersects with the
153     * specified <code>DateSpan</code>.
154     *
155     * @param span DateSpan to compare to
156     * @return true if this <code>DateSpan</code> intersects with the specified
157     * time.
158     */
159    public boolean intersects(DateSpan span) {
160        return intersects(span.getStart(), span.getEnd());
161    }
162
163    /**
164     * Returns a new <code>DateSpan</code> that is the union of this
165     * <code>DateSpan</code> and <code>span</code>.
166     *
167     * @param span DateSpan to add
168     * @return union of this DateSpan and <code>span</code>
169     */
170    public DateSpan add(DateSpan span) {
171        return add(span.getStart(), span.getEnd());
172    }
173
174    /**
175     * Returns a new <code>DateSpan</code> that is the union of this
176     * <code>DateSpan</code> and the passed in span.
177     *
178     * @param start Start of region to add
179     * @param end End of region to end
180     * @return union of this DateSpan and <code>start</code>, <code>end</code>
181     */
182    public DateSpan add(long start, long end) {
183        return new DateSpan(Math.min(start, getStart()),
184                            Math.max(end, getEnd()));
185    }
186
187
188    /**
189     * {@inheritDoc}
190     */
191    @Override
192    public boolean equals(Object o) {
193        if (o == this) {
194            return true;
195        }
196        if (o instanceof DateSpan) {
197            DateSpan ds = (DateSpan)o;
198            return (_start == ds.getStart() && _end == ds.getEnd());
199        }
200        return false;
201    }
202
203    /**
204     * {@inheritDoc}
205     */
206    @Override
207    public int hashCode() {
208        int result = 17;
209        result = 37 * result + (int)(_start ^ (_start >>> 32));
210        result = 37 * result + (int)(_end ^ (_end >>> 32));
211        return result;
212    }
213
214    /**
215     * {@inheritDoc}
216     */
217    @Override
218    public String toString() {
219        return "DateSpan [" + getStartAsDate() + "-" + getEndAsDate() + "]";
220    }
221}