Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2005, 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: * Year.java 29: * --------- 30: * (C) Copyright 2001-2005, by Object Refinery Limited. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): -; 34: * 35: * $Id: Year.java,v 1.9.2.2 2006/08/24 10:01:52 mungady Exp $ 36: * 37: * Changes 38: * ------- 39: * 11-Oct-2001 : Version 1 (DG); 40: * 14-Nov-2001 : Override for toString() method (DG); 41: * 19-Dec-2001 : Added a new constructor as suggested by Paul English (DG); 42: * 29-Jan-2002 : Worked on parseYear() method (DG); 43: * 14-Feb-2002 : Fixed bug in Year(Date) constructor (DG); 44: * 26-Feb-2002 : Changed getStart(), getMiddle() and getEnd() methods to 45: * evaluate with reference to a particular time zone (DG); 46: * 19-Mar-2002 : Changed API for TimePeriod classes (DG); 47: * 10-Sep-2002 : Added getSerialIndex() method (DG); 48: * 04-Oct-2002 : Fixed errors reported by Checkstyle (DG); 49: * 10-Jan-2003 : Changed base class and method names (DG); 50: * 05-Mar-2003 : Fixed bug in getFirstMillisecond() picked up in JUnit 51: * tests (DG); 52: * 13-Mar-2003 : Moved to com.jrefinery.data.time package, and implemented 53: * Serializable (DG); 54: * 21-Oct-2003 : Added hashCode() method (DG); 55: * 56: */ 57: 58: package org.jfree.data.time; 59: 60: import java.io.Serializable; 61: import java.util.Calendar; 62: import java.util.Date; 63: import java.util.TimeZone; 64: 65: import org.jfree.date.MonthConstants; 66: import org.jfree.date.SerialDate; 67: 68: /** 69: * Represents a year in the range 1900 to 9999. This class is immutable, which 70: * is a requirement for all {@link RegularTimePeriod} subclasses. 71: */ 72: public class Year extends RegularTimePeriod implements Serializable { 73: 74: /** For serialization. */ 75: private static final long serialVersionUID = -7659990929736074836L; 76: 77: /** The year. */ 78: private int year; 79: 80: /** 81: * Creates a new <code>Year</code>, based on the current system date/time. 82: */ 83: public Year() { 84: this(new Date()); 85: } 86: 87: /** 88: * Creates a time period representing a single year. 89: * 90: * @param year the year. 91: */ 92: public Year(int year) { 93: 94: // check arguments... 95: if ((year < SerialDate.MINIMUM_YEAR_SUPPORTED) 96: || (year > SerialDate.MAXIMUM_YEAR_SUPPORTED)) { 97: 98: throw new IllegalArgumentException( 99: "Year constructor: year (" + year + ") outside valid range."); 100: } 101: 102: // initialise... 103: this.year = year; 104: 105: } 106: 107: /** 108: * Creates a new <code>Year</code>, based on a particular instant in time, 109: * using the default time zone. 110: * 111: * @param time the time (<code>null</code> not permitted). 112: */ 113: public Year(Date time) { 114: this(time, RegularTimePeriod.DEFAULT_TIME_ZONE); 115: } 116: 117: /** 118: * Constructs a year, based on a particular instant in time and a time zone. 119: * 120: * @param time the time. 121: * @param zone the time zone. 122: */ 123: public Year(Date time, TimeZone zone) { 124: 125: Calendar calendar = Calendar.getInstance(zone); 126: calendar.setTime(time); 127: this.year = calendar.get(Calendar.YEAR); 128: 129: } 130: 131: /** 132: * Returns the year. 133: * 134: * @return The year. 135: */ 136: public int getYear() { 137: return this.year; 138: } 139: 140: /** 141: * Returns the year preceding this one. 142: * 143: * @return The year preceding this one (or <code>null</code> if the 144: * current year is 1900). 145: */ 146: public RegularTimePeriod previous() { 147: if (this.year > SerialDate.MINIMUM_YEAR_SUPPORTED) { 148: return new Year(this.year - 1); 149: } 150: else { 151: return null; 152: } 153: } 154: 155: /** 156: * Returns the year following this one. 157: * 158: * @return The year following this one (or <code>null</code> if the current 159: * year is 9999). 160: */ 161: public RegularTimePeriod next() { 162: if (this.year < SerialDate.MAXIMUM_YEAR_SUPPORTED) { 163: return new Year(this.year + 1); 164: } 165: else { 166: return null; 167: } 168: } 169: 170: /** 171: * Returns a serial index number for the year. 172: * <P> 173: * The implementation simply returns the year number (e.g. 2002). 174: * 175: * @return The serial index number. 176: */ 177: public long getSerialIndex() { 178: return this.year; 179: } 180: 181: /** 182: * Returns the first millisecond of the year, evaluated using the supplied 183: * calendar (which determines the time zone). 184: * 185: * @param calendar the calendar. 186: * 187: * @return The first millisecond of the year. 188: */ 189: public long getFirstMillisecond(Calendar calendar) { 190: Day jan1 = new Day(1, MonthConstants.JANUARY, this.year); 191: return jan1.getFirstMillisecond(calendar); 192: } 193: 194: /** 195: * Returns the last millisecond of the year, evaluated using the supplied 196: * calendar (which determines the time zone). 197: * 198: * @param calendar the calendar. 199: * 200: * @return The last millisecond of the year. 201: */ 202: public long getLastMillisecond(Calendar calendar) { 203: Day dec31 = new Day(31, MonthConstants.DECEMBER, this.year); 204: return dec31.getLastMillisecond(calendar); 205: } 206: 207: /** 208: * Tests the equality of this <code>Year</code> object to an arbitrary 209: * object. Returns <code>true</code> if the target is a <code>Year</code> 210: * instance representing the same year as this object. In all other cases, 211: * returns <code>false</code>. 212: * 213: * @param object the object. 214: * 215: * @return <code>true</code> if the year of this and the object are the 216: * same. 217: */ 218: public boolean equals(Object object) { 219: if (object != null) { 220: if (object instanceof Year) { 221: Year target = (Year) object; 222: return (this.year == target.getYear()); 223: } 224: else { 225: return false; 226: } 227: } 228: else { 229: return false; 230: } 231: } 232: 233: /** 234: * Returns a hash code for this object instance. The approach described by 235: * Joshua Bloch in "Effective Java" has been used here: 236: * <p> 237: * <code>http://developer.java.sun.com/developer/Books/effectivejava 238: * /Chapter3.pdf</code> 239: * 240: * @return A hash code. 241: */ 242: public int hashCode() { 243: int result = 17; 244: int c = this.year; 245: result = 37 * result + c; 246: return result; 247: } 248: 249: /** 250: * Returns an integer indicating the order of this <code>Year</code> object 251: * relative to the specified object: 252: * 253: * negative == before, zero == same, positive == after. 254: * 255: * @param o1 the object to compare. 256: * 257: * @return negative == before, zero == same, positive == after. 258: */ 259: public int compareTo(Object o1) { 260: 261: int result; 262: 263: // CASE 1 : Comparing to another Year object 264: // ----------------------------------------- 265: if (o1 instanceof Year) { 266: Year y = (Year) o1; 267: result = this.year - y.getYear(); 268: } 269: 270: // CASE 2 : Comparing to another TimePeriod object 271: // ----------------------------------------------- 272: else if (o1 instanceof RegularTimePeriod) { 273: // more difficult case - evaluate later... 274: result = 0; 275: } 276: 277: // CASE 3 : Comparing to a non-TimePeriod object 278: // --------------------------------------------- 279: else { 280: // consider time periods to be ordered after general objects 281: result = 1; 282: } 283: 284: return result; 285: 286: } 287: 288: /** 289: * Returns a string representing the year.. 290: * 291: * @return A string representing the year. 292: */ 293: public String toString() { 294: return Integer.toString(this.year); 295: } 296: 297: /** 298: * Parses the string argument as a year. 299: * <P> 300: * The string format is YYYY. 301: * 302: * @param s a string representing the year. 303: * 304: * @return <code>null</code> if the string is not parseable, the year 305: * otherwise. 306: */ 307: public static Year parseYear(String s) { 308: 309: // parse the string... 310: int y; 311: try { 312: y = Integer.parseInt(s.trim()); 313: } 314: catch (NumberFormatException e) { 315: throw new TimePeriodFormatException("Cannot parse string."); 316: } 317: 318: // create the year... 319: try { 320: return new Year(y); 321: } 322: catch (IllegalArgumentException e) { 323: throw new TimePeriodFormatException("Year outside valid range."); 324: } 325: } 326: 327: }