001// Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 
002// The Molly framework is freely distributable under the terms of an
003// MIT-style license. For details, see the molly pages web site at:
004// http://www.mollypages.org/. Use, modify, have fun !
005
006package fc.util;
007
008import java.util.*;
009
010/** 
011A range of dates.
012<p>
013
014@author hursh jain
015**/
016public class DateRange extends Range
017{
018Date start;
019Date end;
020
021/** 
022Constructs a date range between the specified start and end 
023dates (both inclusive).
024
025@throws IllegalArgumentException 
026    if the end date is lesser (via an <tt>compareTo</tt> 
027    comparison) than the start date (equal to the start date 
028    is ok)
029**/
030public DateRange(Date start, Date end) 
031  {
032  Argcheck.istrue(start.compareTo(end) <= 0, "end lesser than start in the specified range, start=["+start+"], end=["+end+"]");
033  this.start = start;
034  this.end = end;
035  }
036
037/** Get the start date for this range **/
038public Date getStart() 
039  {
040  return start;
041  }
042
043
044/** Get the end date for this range **/
045public Date getEnd() 
046  {
047  return end;
048  }
049  
050/** 
051@return true if the passed in date is inside this range. Note,
052the <u>entire</u> date (including the milliseconds/seconds portion)
053is considered by this function.
054
055@throws IllegalArgumentException
056    if the specified date was null
057**/
058public boolean inRange(Date d) 
059  {
060  Argcheck.notnull(d);
061  boolean result = d.compareTo(start) >= 0 &&
062           d.compareTo(end) <= 0;
063  
064  if (negated)
065    return !result;
066  else
067    return result;
068  }
069 
070 
071/** 
072@return true if any part of the passed in date range overlaps this range. Note,
073the <u>entire</u> date (including the milliseconds/seconds portion) is considered by this function.
074
075@throws IllegalArgumentException
076    if the specified date was null
077**/
078public boolean overlaps(DateRange dr) 
079  {
080  Argcheck.notnull(dr);
081  
082  boolean result = inRange(dr.getStart()) || inRange(dr.getEnd());      
083  if (negated)
084    return !result;
085  else
086    return result;
087  } 
088
089 
090/** 
091Set the start date for this range 
092
093@throws NullPointerException
094    if the specified date was null
095@throws IllegalArgumentException 
096    if the specified date is greater (via an <tt>compareTo</tt> 
097    comparison) than the currently set end date (equal to the 
098    end date is ok)
099**/
100public void setStart(Date d) 
101  {
102  Argcheck.notnull(d, "specified argument was null");
103  Argcheck.istrue(d.compareTo(end) <= 0, "start greater than end date, specified start=["+d+"], end=["+end+"]");
104  start = d;
105  }
106
107/** 
108Sets the end date for this range 
109
110@param  d the end date
111
112@throws NullPointerException
113    if the specified date was null
114@throws IllegalArgumentException 
115        if the specified end date is lesser (via an <tt>compareTo</tt> 
116    comparison) than the currently set start date (equal to 
117    the start date is ok)
118**/
119public void setEnd(Date d) 
120  {
121  Argcheck.notnull(d, "specified argument was null");
122  Argcheck.istrue(d.compareTo(start) >= 0, "end lesser than start, start=["+start+"], specified end=["+d+"]");
123  end = d;
124  }
125
126
127/** Output a string representation of the date range **/
128public java.lang.String toString() 
129  {
130  String str = "DateRange:[";
131  if (isNegated())
132    str += "^";
133  str += start + "," + end + "]";
134  return str;
135  }
136
137public static void main(String[] args)
138  {
139  Calendar cal = Calendar.getInstance();
140  Date d1 = cal.getTime();
141  
142  //roll back 1 month
143//  cal.set(Calendar.MONTH, false);
144  cal.add(Calendar.MONTH, -1);
145  Date d2 = cal.getTime();
146     
147  DateRange r = new DateRange(d2, d1);
148  System.out.println("constructed range:" + r);
149  //normal
150  test(r);
151  
152  System.out.println();
153
154  DateRange r2 = new DateRange(d2, new Date(d1.getTime() - CalendarUtil.ONE_DAY));
155  System.out.println("r1:" + r + "\n    -- overlaps? --\n" + "r2:" + r2);
156  System.out.println();
157  System.out.println("r1 overlaps r2 (should be true): " + r.overlaps(r2));
158  System.out.println("r2 overlaps r1 (should be true): " + r2.overlaps(r));
159
160  System.out.println("----------------------------------");
161
162  r2 = new DateRange(
163    new Date(d1.getTime() + CalendarUtil.ONE_DAY),
164    new Date(d1.getTime() + CalendarUtil.THREE_DAY));
165
166  System.out.println("r1:" + r + "\n    -- overlaps? --\n" + "r2:" + r2);
167  System.out.println();
168  System.out.println("r1 overlaps r2 (should be false): " + r.overlaps(r2));
169  System.out.println("r2 overlaps r1 (should be false): " + r2.overlaps(r));
170
171  System.out.println("----------------------------------");
172
173  r2 = new DateRange(
174    new Date(d2.getTime() - CalendarUtil.THREE_DAY),
175    new Date(d2.getTime() - CalendarUtil.ONE_DAY));
176
177  System.out.println("r1:" + r + "\n    -- overlaps? --\n" + "r2:" + r2);
178  System.out.println();
179  System.out.println("r1 overlaps r2 (should be false): " + r.overlaps(r2));
180  System.out.println("r2 overlaps r1 (should be false): " + r2.overlaps(r));
181
182  System.out.println("----------------------------------");
183
184  }
185
186private static void test(DateRange r) 
187  {
188  Date d = new Date();
189
190  System.out.println("in range: " + d + "=" + r.inRange(d));
191
192  Calendar cal = Calendar.getInstance();
193  cal.setTime(d);
194  cal.add(Calendar.MONTH, -2);
195
196  d = cal.getTime();
197  System.out.println("in range: " + d + "=" + r.inRange(d));
198  
199  cal.add(Calendar.MONTH, 2);
200  cal.roll(Calendar.DAY_OF_MONTH, false);
201  d = cal.getTime();  
202  System.out.println("in range: " + d + "=" + r.inRange(d));
203  }
204
205}          //~class CharRange