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: * Second.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: Second.java,v 1.6.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 Second(Date) constructor, and changed start of 43: * range to zero from 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 parseSecond() method (DG); 47: * 10-Sep-2002 : Added getSerialIndex() method (DG); 48: * 07-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 getLastMillisecond() 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: /** 66: * Represents a second in a particular day. This class is immutable, which is 67: * a requirement for all {@link RegularTimePeriod} subclasses. 68: */ 69: public class Second extends RegularTimePeriod implements Serializable { 70: 71: /** For serialization. */ 72: private static final long serialVersionUID = -6536564190712383466L; 73: 74: /** Useful constant for the first second in a minute. */ 75: public static final int FIRST_SECOND_IN_MINUTE = 0; 76: 77: /** Useful constant for the last second in a minute. */ 78: public static final int LAST_SECOND_IN_MINUTE = 59; 79: 80: /** The minute. */ 81: private Minute minute; 82: 83: /** The second. */ 84: private int second; 85: 86: /** 87: * Constructs a new Second, based on the system date/time. 88: */ 89: public Second() { 90: this(new Date()); 91: } 92: 93: /** 94: * Constructs a new Second. 95: * 96: * @param second the second (0 to 24*60*60-1). 97: * @param minute the minute (<code>null</code> not permitted). 98: */ 99: public Second(int second, Minute minute) { 100: if (minute == null) { 101: throw new IllegalArgumentException("Null 'minute' argument."); 102: } 103: this.minute = minute; 104: this.second = second; 105: } 106: 107: /** 108: * Creates a new second. 109: * 110: * @param second the second (0-59). 111: * @param minute the minute (0-59). 112: * @param hour the hour (0-23). 113: * @param day the day (1-31). 114: * @param month the month (1-12). 115: * @param year the year (1900-9999). 116: */ 117: public Second(int second, int minute, int hour, 118: int day, int month, int year) { 119: this(second, new Minute(minute, hour, day, month, year)); 120: } 121: 122: /** 123: * Constructs a second. 124: * 125: * @param time the time. 126: */ 127: public Second(Date time) { 128: this(time, RegularTimePeriod.DEFAULT_TIME_ZONE); 129: } 130: 131: /** 132: * Creates a new second based on the supplied time and time zone. 133: * 134: * @param time the instant in time. 135: * @param zone the time zone. 136: */ 137: public Second(Date time, final TimeZone zone) { 138: this.minute = new Minute(time, zone); 139: Calendar calendar = Calendar.getInstance(zone); 140: calendar.setTime(time); 141: this.second = calendar.get(Calendar.SECOND); 142: } 143: 144: /** 145: * Returns the second within the minute. 146: * 147: * @return The second (0 - 59). 148: */ 149: public int getSecond() { 150: return this.second; 151: } 152: 153: /** 154: * Returns the minute. 155: * 156: * @return The minute (never <code>null</code>). 157: */ 158: public Minute getMinute() { 159: return this.minute; 160: } 161: 162: /** 163: * Returns the second preceding this one. 164: * 165: * @return The second preceding this one. 166: */ 167: public RegularTimePeriod previous() { 168: 169: Second result = null; 170: if (this.second != FIRST_SECOND_IN_MINUTE) { 171: result = new Second(this.second - 1, this.minute); 172: } 173: else { 174: Minute previous = (Minute) this.minute.previous(); 175: if (previous != null) { 176: result = new Second(LAST_SECOND_IN_MINUTE, previous); 177: } 178: } 179: return result; 180: 181: } 182: 183: /** 184: * Returns the second following this one. 185: * 186: * @return The second following this one. 187: */ 188: public RegularTimePeriod next() { 189: 190: Second result = null; 191: if (this.second != LAST_SECOND_IN_MINUTE) { 192: result = new Second(this.second + 1, this.minute); 193: } 194: else { 195: Minute next = (Minute) this.minute.next(); 196: if (next != null) { 197: result = new Second(FIRST_SECOND_IN_MINUTE, next); 198: } 199: } 200: return result; 201: 202: } 203: 204: /** 205: * Returns a serial index number for the minute. 206: * 207: * @return The serial index number. 208: */ 209: public long getSerialIndex() { 210: return this.minute.getSerialIndex() * 60L + this.second; 211: } 212: 213: /** 214: * Returns the first millisecond of the minute. 215: * 216: * @param calendar the calendar/timezone. 217: * 218: * @return The first millisecond. 219: */ 220: public long getFirstMillisecond(Calendar calendar) { 221: return this.minute.getFirstMillisecond(calendar) + this.second * 1000L; 222: } 223: 224: /** 225: * Returns the last millisecond of the second. 226: * 227: * @param calendar the calendar/timezone. 228: * 229: * @return The last millisecond. 230: */ 231: public long getLastMillisecond(Calendar calendar) { 232: return this.minute.getFirstMillisecond(calendar) 233: + this.second * 1000L + 999L; 234: } 235: 236: /** 237: * Tests the equality of this object against an arbitrary Object. 238: * <P> 239: * This method will return true ONLY if the object is a Second object 240: * representing the same second as this instance. 241: * 242: * @param obj the object to compare. 243: * 244: * @return <code>true</code> if second and minute of this and the object 245: * are the same. 246: */ 247: public boolean equals(Object obj) { 248: if (obj instanceof Second) { 249: Second s = (Second) obj; 250: return ((this.second == s.getSecond()) 251: && (this.minute.equals(s.getMinute()))); 252: } 253: else { 254: return false; 255: } 256: } 257: 258: /** 259: * Returns a hash code for this object instance. The approach described by 260: * Joshua Bloch in "Effective Java" has been used here: 261: * <p> 262: * <code>http://developer.java.sun.com/developer/Books/effectivejava 263: * /Chapter3.pdf</code> 264: * 265: * @return A hash code. 266: */ 267: public int hashCode() { 268: int result = 17; 269: result = 37 * result + this.second; 270: result = 37 * result + this.minute.hashCode(); 271: return result; 272: } 273: 274: /** 275: * Returns an integer indicating the order of this Second object relative 276: * to the specified 277: * object: negative == before, zero == same, positive == after. 278: * 279: * @param o1 the object to compare. 280: * 281: * @return negative == before, zero == same, positive == after. 282: */ 283: public int compareTo(Object o1) { 284: 285: int result; 286: 287: // CASE 1 : Comparing to another Second object 288: // ------------------------------------------- 289: if (o1 instanceof Second) { 290: Second s = (Second) o1; 291: result = this.minute.compareTo(s.minute); 292: if (result == 0) { 293: result = this.second - s.second; 294: } 295: } 296: 297: // CASE 2 : Comparing to another TimePeriod object 298: // ----------------------------------------------- 299: else if (o1 instanceof RegularTimePeriod) { 300: // more difficult case - evaluate later... 301: result = 0; 302: } 303: 304: // CASE 3 : Comparing to a non-TimePeriod object 305: // --------------------------------------------- 306: else { 307: // consider time periods to be ordered after general objects 308: result = 1; 309: } 310: 311: return result; 312: 313: } 314: 315: /** 316: * Creates a new instance by parsing a string. The string is assumed to 317: * be in the format "YYYY-MM-DD HH:MM:SS", perhaps with leading or trailing 318: * whitespace. 319: * 320: * @param s the string to parse. 321: * 322: * @return The second, or <code>null</code> if the string is not parseable. 323: */ 324: public static Second parseSecond(String s) { 325: 326: Second result = null; 327: s = s.trim(); 328: 329: String daystr = s.substring(0, Math.min(10, s.length())); 330: Day day = Day.parseDay(daystr); 331: if (day != null) { 332: String hmsstr = s.substring( 333: Math.min(daystr.length() + 1, s.length()), s.length() 334: ); 335: hmsstr = hmsstr.trim(); 336: 337: int l = hmsstr.length(); 338: String hourstr = hmsstr.substring(0, Math.min(2, l)); 339: String minstr = hmsstr.substring(Math.min(3, l), Math.min(5, l)); 340: String secstr = hmsstr.substring(Math.min(6, l), Math.min(8, l)); 341: int hour = Integer.parseInt(hourstr); 342: 343: if ((hour >= 0) && (hour <= 23)) { 344: 345: int minute = Integer.parseInt(minstr); 346: if ((minute >= 0) && (minute <= 59)) { 347: 348: Minute m = new Minute(minute, new Hour(hour, day)); 349: int second = Integer.parseInt(secstr); 350: if ((second >= 0) && (second <= 59)) { 351: result = new Second(second, m); 352: } 353: } 354: } 355: } 356: 357: return result; 358: 359: } 360: 361: }