Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jfreechart/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * License for more details. 18: * 19: * You should have received a copy of the GNU Lesser General Public 20: * License along with this library; if not, write to the Free Software 21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * ---------------------- 28: * RegularTimePeriod.java 29: * ---------------------- 30: * (C) Copyright 2001-2006, by Object Refinery Limited. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): -; 34: * 35: * $Id: RegularTimePeriod.java,v 1.6.2.2 2006/10/06 14:00:15 mungady Exp $ 36: * 37: * Changes 38: * ------- 39: * 11-Oct-2001 : Version 1 (DG); 40: * 26-Feb-2002 : Changed getStart(), getMiddle() and getEnd() methods to 41: * evaluate with reference to a particular time zone (DG); 42: * 29-May-2002 : Implemented MonthConstants interface, so that these constants 43: * are conveniently available (DG); 44: * 10-Sep-2002 : Added getSerialIndex() method (DG); 45: * 10-Jan-2003 : Renamed TimePeriod --> RegularTimePeriod (DG); 46: * 13-Mar-2003 : Moved to com.jrefinery.data.time package (DG); 47: * 29-Apr-2004 : Changed getMiddleMillisecond() methods to fix bug 943985 (DG); 48: * 25-Nov-2004 : Added utility methods (DG); 49: * ------------- JFREECHART 1.0.x --------------------------------------------- 50: * 06-Oct-2006 : Deprecated the WORKING_CALENDAR field and several methods, 51: * added new peg() method (DG); 52: * 53: */ 54: 55: package org.jfree.data.time; 56: 57: import java.lang.reflect.Constructor; 58: import java.util.Calendar; 59: import java.util.Date; 60: import java.util.TimeZone; 61: 62: import org.jfree.date.MonthConstants; 63: 64: /** 65: * An abstract class representing a unit of time. Convenient methods are 66: * provided for calculating the next and previous time periods. Conversion 67: * methods are defined that return the first and last milliseconds of the time 68: * period. The results from these methods are timezone dependent. 69: * <P> 70: * This class is immutable, and all subclasses should be immutable also. 71: */ 72: public abstract class RegularTimePeriod implements TimePeriod, Comparable, 73: MonthConstants { 74: 75: /** 76: * Creates a time period that includes the specified millisecond, assuming 77: * the given time zone. 78: * 79: * @param c the time period class. 80: * @param millisecond the time. 81: * @param zone the time zone. 82: * 83: * @return The time period. 84: */ 85: public static RegularTimePeriod createInstance(Class c, Date millisecond, 86: TimeZone zone) { 87: RegularTimePeriod result = null; 88: try { 89: Constructor constructor = c.getDeclaredConstructor( 90: new Class[] {Date.class, TimeZone.class}); 91: result = (RegularTimePeriod) constructor.newInstance( 92: new Object[] {millisecond, zone}); 93: } 94: catch (Exception e) { 95: // do nothing, so null is returned 96: } 97: return result; 98: } 99: 100: /** 101: * Returns a subclass of {@link RegularTimePeriod} that is smaller than 102: * the specified class. 103: * 104: * @param c a subclass of {@link RegularTimePeriod}. 105: * 106: * @return A class. 107: */ 108: public static Class downsize(Class c) { 109: if (c.equals(Year.class)) { 110: return Quarter.class; 111: } 112: else if (c.equals(Quarter.class)) { 113: return Month.class; 114: } 115: else if (c.equals(Month.class)) { 116: return Day.class; 117: } 118: else if (c.equals(Day.class)) { 119: return Hour.class; 120: } 121: else if (c.equals(Hour.class)) { 122: return Minute.class; 123: } 124: else if (c.equals(Minute.class)) { 125: return Second.class; 126: } 127: else if (c.equals(Second.class)) { 128: return Millisecond.class; 129: } 130: else { 131: return Millisecond.class; 132: } 133: } 134: 135: /** 136: * Returns the time period preceding this one, or <code>null</code> if some 137: * lower limit has been reached. 138: * 139: * @return The previous time period (possibly <code>null</code>). 140: */ 141: public abstract RegularTimePeriod previous(); 142: 143: /** 144: * Returns the time period following this one, or <code>null</code> if some 145: * limit has been reached. 146: * 147: * @return The next time period (possibly <code>null</code>). 148: */ 149: public abstract RegularTimePeriod next(); 150: 151: /** 152: * Returns a serial index number for the time unit. 153: * 154: * @return The serial index number. 155: */ 156: public abstract long getSerialIndex(); 157: 158: ////////////////////////////////////////////////////////////////////////// 159: 160: /** 161: * The default time zone. 162: */ 163: public static final TimeZone DEFAULT_TIME_ZONE = TimeZone.getDefault(); 164: 165: /** 166: * A working calendar (recycle to avoid unnecessary object creation). 167: * 168: * @deprecated This was a bad idea, don't use it! 169: */ 170: public static final Calendar WORKING_CALENDAR 171: = Calendar.getInstance(DEFAULT_TIME_ZONE); 172: 173: /** 174: * Recalculates the start date/time and end date/time for this time period 175: * relative to the supplied calendar (which incorporates a time zone). 176: * 177: * @param calendar the calendar (<code>null</code> not permitted). 178: * 179: * @since 1.0.3 180: */ 181: public abstract void peg(Calendar calendar); 182: 183: /** 184: * Returns the date/time that marks the start of the time period. This 185: * method returns a new <code>Date</code> instance every time it is called. 186: * 187: * @return The start date/time. 188: * 189: * @see #getFirstMillisecond() 190: */ 191: public Date getStart() { 192: return new Date(getFirstMillisecond()); 193: } 194: 195: /** 196: * Returns the date/time that marks the end of the time period. This 197: * method returns a new <code>Date</code> instance every time it is called. 198: * 199: * @return The end date/time. 200: * 201: * @see #getLastMillisecond() 202: */ 203: public Date getEnd() { 204: return new Date(getLastMillisecond()); 205: } 206: 207: /** 208: * Returns the first millisecond of the time period. This will be 209: * determined relative to the time zone specified in the constructor, or 210: * in the calendar instance passed in the most recent call to the 211: * {@link #peg(Calendar)} method. 212: * 213: * @return The first millisecond of the time period. 214: * 215: * @see #getLastMillisecond() 216: */ 217: public abstract long getFirstMillisecond(); 218: 219: /** 220: * Returns the first millisecond of the time period, evaluated within a 221: * specific time zone. 222: * 223: * @param zone the time zone (<code>null</code> not permitted). 224: * 225: * @return The first millisecond of the time period. 226: * 227: * @deprecated As of 1.0.3, you should avoid using this method (it creates 228: * a new Calendar instance every time it is called). You are advised 229: * to call {@link #getFirstMillisecond(Calendar)} instead. 230: * 231: * @see #getLastMillisecond(TimeZone) 232: */ 233: public long getFirstMillisecond(TimeZone zone) { 234: Calendar calendar = Calendar.getInstance(zone); 235: return getFirstMillisecond(calendar); 236: } 237: 238: /** 239: * Returns the first millisecond of the time period, evaluated using the 240: * supplied calendar (which incorporates a timezone). 241: * 242: * @param calendar the calendar (<code>null</code> not permitted). 243: * 244: * @return The first millisecond of the time period. 245: * 246: * @throws NullPointerException if <code>calendar,/code> is 247: * </code>null</code>. 248: * 249: * @see #getLastMillisecond(Calendar) 250: */ 251: public abstract long getFirstMillisecond(Calendar calendar); 252: 253: /** 254: * Returns the last millisecond of the time period. This will be 255: * determined relative to the time zone specified in the constructor, or 256: * in the calendar instance passed in the most recent call to the 257: * {@link #peg(Calendar)} method. 258: * 259: * @return The last millisecond of the time period. 260: * 261: * @see #getFirstMillisecond() 262: */ 263: public abstract long getLastMillisecond(); 264: 265: /** 266: * Returns the last millisecond of the time period, evaluated within a 267: * specific time zone. 268: * 269: * @param zone the time zone (<code>null</code> not permitted). 270: * 271: * @return The last millisecond of the time period. 272: * 273: * @deprecated As of 1.0.3, you should avoid using this method (it creates 274: * a new Calendar instance every time it is called). You are advised 275: * to call {@link #getLastMillisecond(Calendar)} instead. 276: * 277: * @see #getFirstMillisecond(TimeZone) 278: */ 279: public long getLastMillisecond(TimeZone zone) { 280: Calendar calendar = Calendar.getInstance(zone); 281: return getLastMillisecond(calendar); 282: } 283: 284: /** 285: * Returns the last millisecond of the time period, evaluated using the 286: * supplied calendar (which incorporates a timezone). 287: * 288: * @param calendar the calendar (<code>null</code> not permitted). 289: * 290: * @return The last millisecond of the time period. 291: * 292: * @see #getFirstMillisecond(Calendar) 293: */ 294: public abstract long getLastMillisecond(Calendar calendar); 295: 296: /** 297: * Returns the millisecond closest to the middle of the time period. 298: * 299: * @return The middle millisecond. 300: */ 301: public long getMiddleMillisecond() { 302: long m1 = getFirstMillisecond(); 303: long m2 = getLastMillisecond(); 304: return m1 + (m2 - m1) / 2; 305: } 306: 307: /** 308: * Returns the millisecond closest to the middle of the time period, 309: * evaluated within a specific time zone. 310: * 311: * @param zone the time zone (<code>null</code> not permitted). 312: * 313: * @return The middle millisecond. 314: * 315: * @deprecated As of 1.0.3, you should avoid using this method (it creates 316: * a new Calendar instance every time it is called). You are advised 317: * to call {@link #getMiddleMillisecond(Calendar)} instead. 318: */ 319: public long getMiddleMillisecond(TimeZone zone) { 320: Calendar calendar = Calendar.getInstance(zone); 321: long m1 = getFirstMillisecond(calendar); 322: long m2 = getLastMillisecond(calendar); 323: return m1 + (m2 - m1) / 2; 324: } 325: 326: /** 327: * Returns the millisecond closest to the middle of the time period, 328: * evaluated using the supplied calendar (which incorporates a timezone). 329: * 330: * @param calendar the calendar. 331: * 332: * @return The middle millisecond. 333: */ 334: public long getMiddleMillisecond(Calendar calendar) { 335: long m1 = getFirstMillisecond(calendar); 336: long m2 = getLastMillisecond(calendar); 337: return m1 + (m2 - m1) / 2; 338: } 339: 340: /** 341: * Returns a string representation of the time period. 342: * 343: * @return The string. 344: */ 345: public String toString() { 346: return String.valueOf(getStart()); 347: } 348: 349: }