001    /*
002     * $Id: DateSpan.java,v 1.3 2005/10/10 18:02:46 rbair Exp $
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     */
021    package org.jdesktop.swingx.calendar;
022    
023    import 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: 1.3 $
033     */
034    public 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    }