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: * Minute.java 29: * ----------- 30: * (C) Copyright 2001-2004, by Object Refinery Limited. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): -; 34: * 35: * $Id: Minute.java,v 1.5.2.1 2005/10/25 21:35:24 mungady Exp $ 36: * 37: * Changes 38: * ------- 39: * 11-Oct-2001 : Version 1 (DG); 40: * 18-Dec-2001 : Changed order of parameters in constructor (DG); 41: * 19-Dec-2001 : Added a new constructor as suggested by Paul English (DG); 42: * 14-Feb-2002 : Fixed bug in Minute(Date) constructor, and changed the range 43: * to start from zero instead of one (DG); 44: * 26-Feb-2002 : Changed getStart(), getMiddle() and getEnd() methods to 45: * evaluate with reference to a particular time zone (DG); 46: * 13-Mar-2002 : Added parseMinute() method (DG); 47: * 19-Mar-2002 : Changed API, the minute is now defined in relation to an 48: * Hour (DG); 49: * 10-Sep-2002 : Added getSerialIndex() method (DG); 50: * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG); 51: * 10-Jan-2003 : Changed base class and method names (DG); 52: * 13-Mar-2003 : Moved to com.jrefinery.data.time package and implemented 53: * Serializable (DG); 54: * 21-Oct-2003 : Added hashCode() method, and new constructor for 55: * convenience (DG); 56: * 30-Sep-2004 : Replaced getTime().getTime() with getTimeInMillis() (DG); 57: * 04-Nov-2004 : Reverted change of 30-Sep-2004, because it won't work for 58: * JDK 1.3 (DG); 59: * 60: */ 61: 62: package org.jfree.data.time; 63: 64: import java.io.Serializable; 65: import java.util.Calendar; 66: import java.util.Date; 67: import java.util.TimeZone; 68: 69: /** 70: * Represents a minute. This class is immutable, which is a requirement for 71: * all {@link RegularTimePeriod} subclasses. 72: */ 73: public class Minute extends RegularTimePeriod implements Serializable { 74: 75: /** For serialization. */ 76: private static final long serialVersionUID = 2144572840034842871L; 77: 78: /** Useful constant for the first minute in a day. */ 79: public static final int FIRST_MINUTE_IN_HOUR = 0; 80: 81: /** Useful constant for the last minute in a day. */ 82: public static final int LAST_MINUTE_IN_HOUR = 59; 83: 84: /** The hour in which the minute falls. */ 85: private Hour hour; 86: 87: /** The minute. */ 88: private int minute; 89: 90: /** 91: * Constructs a new Minute, based on the system date/time. 92: */ 93: public Minute() { 94: this(new Date()); 95: } 96: 97: /** 98: * Constructs a new Minute. 99: * 100: * @param minute the minute (0 to 59). 101: * @param hour the hour (<code>null</code> not permitted). 102: */ 103: public Minute(int minute, Hour hour) { 104: if (hour == null) { 105: throw new IllegalArgumentException("Null 'hour' argument."); 106: } 107: this.minute = minute; 108: this.hour = hour; 109: } 110: 111: /** 112: * Constructs a new Minute, based on the supplied date/time. 113: * 114: * @param time the time (<code>null</code> not permitted). 115: */ 116: public Minute(Date time) { 117: // defer argument checking 118: this(time, RegularTimePeriod.DEFAULT_TIME_ZONE); 119: } 120: 121: /** 122: * Constructs a new Minute, based on the supplied date/time and timezone. 123: * 124: * @param time the time (<code>null</code> not permitted). 125: * @param zone the time zone (<code>null</code> not permitted). 126: */ 127: public Minute(Date time, TimeZone zone) { 128: 129: if (time == null) { 130: throw new IllegalArgumentException("Null 'time' argument."); 131: } 132: if (zone == null) { 133: throw new IllegalArgumentException("Null 'zone' argument."); 134: } 135: Calendar calendar = Calendar.getInstance(zone); 136: calendar.setTime(time); 137: int min = calendar.get(Calendar.MINUTE); 138: this.minute = min; 139: this.hour = new Hour(time, zone); 140: 141: } 142: 143: /** 144: * Creates a new minute. 145: * 146: * @param minute the minute (0-59). 147: * @param hour the hour (0-23). 148: * @param day the day (1-31). 149: * @param month the month (1-12). 150: * @param year the year (1900-9999). 151: */ 152: public Minute(int minute, 153: int hour, 154: int day, 155: int month, 156: int year) { 157: this(minute, new Hour(hour, new Day(day, month, year))); 158: } 159: 160: /** 161: * Returns the hour. 162: * 163: * @return The hour (never <code>null</code>). 164: */ 165: public Hour getHour() { 166: return this.hour; 167: } 168: 169: /** 170: * Returns the minute. 171: * 172: * @return The minute. 173: */ 174: public int getMinute() { 175: return this.minute; 176: } 177: 178: /** 179: * Returns the minute preceding this one. 180: * 181: * @return The minute preceding this one. 182: */ 183: public RegularTimePeriod previous() { 184: 185: Minute result; 186: if (this.minute != FIRST_MINUTE_IN_HOUR) { 187: result = new Minute(this.minute - 1, this.hour); 188: } 189: else { // we are at the first minute in the hour... 190: Hour prevHour = (Hour) this.hour.previous(); 191: if (prevHour != null) { 192: result = new Minute(LAST_MINUTE_IN_HOUR, prevHour); 193: } 194: else { 195: result = null; 196: } 197: } 198: return result; 199: 200: } 201: 202: /** 203: * Returns the minute following this one. 204: * 205: * @return The minute following this one. 206: */ 207: public RegularTimePeriod next() { 208: 209: Minute result; 210: if (this.minute != LAST_MINUTE_IN_HOUR) { 211: result = new Minute(this.minute + 1, this.hour); 212: } 213: else { // we are at the last minute in the hour... 214: Hour nextHour = (Hour) this.hour.next(); 215: if (nextHour != null) { 216: result = new Minute(FIRST_MINUTE_IN_HOUR, nextHour); 217: } 218: else { 219: result = null; 220: } 221: } 222: return result; 223: 224: } 225: 226: /** 227: * Returns a serial index number for the minute. 228: * 229: * @return The serial index number. 230: */ 231: public long getSerialIndex() { 232: return this.hour.getSerialIndex() * 60L + this.minute; 233: } 234: 235: /** 236: * Returns the first millisecond of the minute. 237: * 238: * @param calendar the calendar (which defines the timezone). 239: * 240: * @return The first millisecond. 241: */ 242: public long getFirstMillisecond(Calendar calendar) { 243: 244: int year = this.hour.getDay().getYear(); 245: int month = this.hour.getDay().getMonth() - 1; 246: int day = this.hour.getDay().getDayOfMonth(); 247: 248: calendar.clear(); 249: calendar.set(year, month, day, this.hour.getHour(), this.minute, 0); 250: calendar.set(Calendar.MILLISECOND, 0); 251: 252: //return calendar.getTimeInMillis(); // this won't work for JDK 1.3 253: return calendar.getTime().getTime(); 254: 255: } 256: 257: /** 258: * Returns the last millisecond of the minute. 259: * 260: * @param calendar the calendar and timezone. 261: * 262: * @return The last millisecond. 263: */ 264: public long getLastMillisecond(Calendar calendar) { 265: 266: int year = this.hour.getDay().getYear(); 267: int month = this.hour.getDay().getMonth() - 1; 268: int day = this.hour.getDay().getDayOfMonth(); 269: 270: calendar.clear(); 271: calendar.set(year, month, day, this.hour.getHour(), this.minute, 59); 272: calendar.set(Calendar.MILLISECOND, 999); 273: 274: //return calendar.getTimeInMillis(); // this won't work for JDK 1.3 275: return calendar.getTime().getTime(); 276: 277: } 278: 279: /** 280: * Tests the equality of this object against an arbitrary Object. 281: * <P> 282: * This method will return true ONLY if the object is a Minute object 283: * representing the same minute as this instance. 284: * 285: * @param obj the object to compare (<code>null</code> permitted). 286: * 287: * @return <code>true</code> if the minute and hour value of this and the 288: * object are the same. 289: */ 290: public boolean equals(Object obj) { 291: if (obj == this) { 292: return true; 293: } 294: if (!(obj instanceof Minute)) { 295: return false; 296: } 297: Minute that = (Minute) obj; 298: if (this.minute != that.minute) { 299: return false; 300: } 301: if (!this.hour.equals(that.hour)) { 302: return false; 303: } 304: return true; 305: } 306: 307: /** 308: * Returns a hash code for this object instance. The approach described 309: * by Joshua Bloch in "Effective Java" has been used here: 310: * <p> 311: * <code>http://developer.java.sun.com/developer/Books/effectivejava 312: * /Chapter3.pdf</code> 313: * 314: * @return A hash code. 315: */ 316: public int hashCode() { 317: int result = 17; 318: result = 37 * result + this.minute; 319: result = 37 * result + this.hour.hashCode(); 320: return result; 321: } 322: 323: /** 324: * Returns an integer indicating the order of this Minute object relative 325: * to the specified object: 326: * 327: * negative == before, zero == same, positive == after. 328: * 329: * @param o1 object to compare. 330: * 331: * @return negative == before, zero == same, positive == after. 332: */ 333: public int compareTo(Object o1) { 334: 335: int result; 336: 337: // CASE 1 : Comparing to another Minute object 338: // ------------------------------------------- 339: if (o1 instanceof Minute) { 340: Minute m = (Minute) o1; 341: result = getHour().compareTo(m.getHour()); 342: if (result == 0) { 343: result = this.minute - m.getMinute(); 344: } 345: } 346: 347: // CASE 2 : Comparing to another TimePeriod object 348: // ----------------------------------------------- 349: else if (o1 instanceof RegularTimePeriod) { 350: // more difficult case - evaluate later... 351: result = 0; 352: } 353: 354: // CASE 3 : Comparing to a non-TimePeriod object 355: // --------------------------------------------- 356: else { 357: // consider time periods to be ordered after general objects 358: result = 1; 359: } 360: 361: return result; 362: 363: } 364: 365: /** 366: * Creates a Minute instance by parsing a string. The string is assumed to 367: * be in the format "YYYY-MM-DD HH:MM", perhaps with leading or trailing 368: * whitespace. 369: * 370: * @param s the minute string to parse. 371: * 372: * @return <code>null</code>, if the string is not parseable, the minute 373: * otherwise. 374: */ 375: public static Minute parseMinute(String s) { 376: 377: Minute result = null; 378: s = s.trim(); 379: 380: String daystr = s.substring(0, Math.min(10, s.length())); 381: Day day = Day.parseDay(daystr); 382: if (day != null) { 383: String hmstr = s.substring( 384: Math.min(daystr.length() + 1, s.length()), s.length() 385: ); 386: hmstr = hmstr.trim(); 387: 388: String hourstr = hmstr.substring(0, Math.min(2, hmstr.length())); 389: int hour = Integer.parseInt(hourstr); 390: 391: if ((hour >= 0) && (hour <= 23)) { 392: String minstr = hmstr.substring( 393: Math.min(hourstr.length() + 1, hmstr.length()), 394: hmstr.length() 395: ); 396: int minute = Integer.parseInt(minstr); 397: if ((minute >= 0) && (minute <= 59)) { 398: result = new Minute(minute, new Hour(hour, day)); 399: } 400: } 401: } 402: 403: return result; 404: 405: } 406: 407: }