Source for org.jfree.data.time.Millisecond

   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:  * Millisecond.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: Millisecond.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:  * 19-Dec-2001 : Added new constructors as suggested by Paul English (DG);
  41:  * 26-Feb-2002 : Added new getStart() and getEnd() methods (DG);
  42:  * 29-Mar-2002 : Fixed bug in getStart(), getEnd() and compareTo() methods (DG);
  43:  * 10-Sep-2002 : Added getSerialIndex() method (DG);
  44:  * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG);
  45:  * 10-Jan-2003 : Changed base class and method names (DG);
  46:  * 13-Mar-2003 : Moved to com.jrefinery.data.time package and implemented 
  47:  *               Serializable (DG);
  48:  * 21-Oct-2003 : Added hashCode() method (DG);
  49:  *
  50:  */
  51: 
  52: package org.jfree.data.time;
  53: 
  54: import java.io.Serializable;
  55: import java.util.Calendar;
  56: import java.util.Date;
  57: import java.util.TimeZone;
  58: 
  59: /**
  60:  * Represents a millisecond.  This class is immutable, which is a requirement 
  61:  * for all {@link RegularTimePeriod} subclasses.
  62:  */
  63: public class Millisecond extends RegularTimePeriod implements Serializable {
  64: 
  65:     /** For serialization. */
  66:     static final long serialVersionUID = -5316836467277638485L;
  67:     
  68:     /** A constant for the first millisecond in a second. */
  69:     public static final int FIRST_MILLISECOND_IN_SECOND = 0;
  70: 
  71:     /** A constant for the last millisecond in a second. */
  72:     public static final int LAST_MILLISECOND_IN_SECOND = 999;
  73: 
  74:     /** The millisecond. */
  75:     private int millisecond;
  76: 
  77:     /** The second. */
  78:     private Second second;
  79: 
  80:     /**
  81:      * Constructs a millisecond based on the current system time.
  82:      */
  83:     public Millisecond() {
  84:         this(new Date());
  85:     }
  86: 
  87:     /**
  88:      * Constructs a millisecond.
  89:      *
  90:      * @param millisecond  the millisecond (0-999).
  91:      * @param second  the second.
  92:      */
  93:     public Millisecond(int millisecond, Second second) {
  94:         this.millisecond = millisecond;
  95:         this.second = second;
  96:     }
  97: 
  98:     /**
  99:      * Creates a new millisecond.
 100:      * 
 101:      * @param millisecond  the millisecond (0-999).
 102:      * @param second  the second (0-59).
 103:      * @param minute  the minute (0-59).
 104:      * @param hour  the hour (0-23).
 105:      * @param day  the day (1-31).
 106:      * @param month  the month (1-12).
 107:      * @param year  the year (1900-9999).
 108:      */    
 109:     public Millisecond(int millisecond, int second, int minute, int hour,
 110:                        int day, int month, int year) {
 111:                            
 112:         this(millisecond, new Second(second, minute, hour, day, month, year));
 113:     
 114:     }
 115: 
 116:     /**
 117:      * Constructs a millisecond.
 118:      *
 119:      * @param time  the time.
 120:      */
 121:     public Millisecond(Date time) {
 122:         this(time, RegularTimePeriod.DEFAULT_TIME_ZONE);
 123:     }
 124: 
 125:     /**
 126:      * Creates a millisecond.
 127:      *
 128:      * @param time  the instant in time.
 129:      * @param zone  the time zone.
 130:      */
 131:     public Millisecond(Date time, TimeZone zone) {
 132: 
 133:         this.second = new Second(time, zone);
 134:         Calendar calendar = Calendar.getInstance(zone);
 135:         calendar.setTime(time);
 136:         this.millisecond = calendar.get(Calendar.MILLISECOND);
 137: 
 138:     }
 139: 
 140:     /**
 141:      * Returns the second.
 142:      *
 143:      * @return The second.
 144:      */
 145:     public Second getSecond() {
 146:         return this.second;
 147:     }
 148: 
 149:     /**
 150:      * Returns the millisecond.
 151:      *
 152:      * @return The millisecond.
 153:      */
 154:     public long getMillisecond() {
 155:         return this.millisecond;
 156:     }
 157: 
 158:     /**
 159:      * Returns the millisecond preceding this one.
 160:      *
 161:      * @return The millisecond preceding this one.
 162:      */
 163:     public RegularTimePeriod previous() {
 164: 
 165:         RegularTimePeriod result = null;
 166: 
 167:         if (this.millisecond != FIRST_MILLISECOND_IN_SECOND) {
 168:             result = new Millisecond(this.millisecond - 1, this.second);
 169:         }
 170:         else {
 171:             Second previous = (Second) this.second.previous();
 172:             if (previous != null) {
 173:                 result = new Millisecond(LAST_MILLISECOND_IN_SECOND, previous);
 174:             }
 175:         }
 176:         return result;
 177: 
 178:     }
 179: 
 180:     /**
 181:      * Returns the millisecond following this one.
 182:      *
 183:      * @return The millisecond following this one.
 184:      */
 185:     public RegularTimePeriod next() {
 186: 
 187:         RegularTimePeriod result = null;
 188:         if (this.millisecond != LAST_MILLISECOND_IN_SECOND) {
 189:             result = new Millisecond(this.millisecond + 1, this.second);
 190:         }
 191:         else {
 192:             Second next = (Second) this.second.next();
 193:             if (next != null) {
 194:                 result = new Millisecond(FIRST_MILLISECOND_IN_SECOND, next);
 195:             }
 196:         }
 197:         return result;
 198: 
 199:     }
 200: 
 201:     /**
 202:      * Returns a serial index number for the millisecond.
 203:      *
 204:      * @return The serial index number.
 205:      */
 206:     public long getSerialIndex() {
 207:         return this.second.getSerialIndex() * 1000L + this.millisecond;
 208:     }
 209: 
 210:     /**
 211:      * Tests the equality of this object against an arbitrary Object.
 212:      * <P>
 213:      * This method will return true ONLY if the object is a Millisecond object
 214:      * representing the same millisecond as this instance.
 215:      *
 216:      * @param obj  the object to compare
 217:      *
 218:      * @return <code>true</code> if milliseconds and seconds of this and object
 219:      *      are the same.
 220:      */
 221:     public boolean equals(Object obj) {
 222: 
 223:         if (obj instanceof Millisecond) {
 224:             Millisecond m = (Millisecond) obj;
 225:             return ((this.millisecond == m.getMillisecond())
 226:                     && (this.second.equals(m.getSecond())));
 227:         }
 228:         else {
 229:             return false;
 230:         }
 231: 
 232:     }
 233: 
 234:     /**
 235:      * Returns a hash code for this object instance.  The approach described by 
 236:      * Joshua Bloch in "Effective Java" has been used here:
 237:      * <p>
 238:      * <code>http://developer.java.sun.com/developer/Books/effectivejava
 239:      * /Chapter3.pdf</code>
 240:      * 
 241:      * @return A hashcode.
 242:      */
 243:     public int hashCode() {
 244:         int result = 17;
 245:         result = 37 * result + this.millisecond;
 246:         result = 37 * result + this.second.hashCode();
 247:         return result;
 248:     }
 249: 
 250:     /**
 251:      * Returns an integer indicating the order of this Millisecond object
 252:      * relative to the specified object:
 253:      *
 254:      * negative == before, zero == same, positive == after.
 255:      *
 256:      * @param obj  the object to compare
 257:      *
 258:      * @return negative == before, zero == same, positive == after.
 259:      */
 260:     public int compareTo(Object obj) {
 261: 
 262:         int result;
 263:         long difference;
 264: 
 265:         // CASE 1 : Comparing to another Second object
 266:         // -------------------------------------------
 267:         if (obj instanceof Millisecond) {
 268:             Millisecond ms = (Millisecond) obj;
 269:             difference = getFirstMillisecond() - ms.getFirstMillisecond();
 270:             if (difference > 0) {
 271:                 result = 1;
 272:             }
 273:             else {
 274:                 if (difference < 0) {
 275:                     result = -1;
 276:                 }
 277:                 else {
 278:                     result = 0;
 279:                 }
 280:             }
 281:         }
 282: 
 283:         // CASE 2 : Comparing to another TimePeriod object
 284:         // -----------------------------------------------
 285:         else if (obj instanceof RegularTimePeriod) {
 286:             // more difficult case - evaluate later...
 287:             result = 0;
 288:         }
 289: 
 290:         // CASE 3 : Comparing to a non-TimePeriod object
 291:         // ---------------------------------------------
 292:         else {
 293:             // consider time periods to be ordered after general objects
 294:             result = 1;
 295:         }
 296: 
 297:         return result;
 298: 
 299:     }
 300: 
 301:     /**
 302:      * Returns the first millisecond of the time period.
 303:      *
 304:      * @return The first millisecond of the time period.
 305:      */
 306:     public long getFirstMillisecond() {
 307:         return this.second.getFirstMillisecond() + this.millisecond;
 308:     }
 309: 
 310:     /**
 311:      * Returns the first millisecond of the time period.
 312:      *
 313:      * @param calendar  the calendar.
 314:      *
 315:      * @return The first millisecond of the time period.
 316:      */
 317:     public long getFirstMillisecond(Calendar calendar) {
 318:         return this.second.getFirstMillisecond(calendar) + this.millisecond;
 319:     }
 320: 
 321:     /**
 322:      * Returns the last millisecond of the time period.
 323:      *
 324:      * @return The last millisecond of the time period.
 325:      */
 326:     public long getLastMillisecond() {
 327:         return this.second.getFirstMillisecond() + this.millisecond;
 328:     }
 329: 
 330:     /**
 331:      * Returns the last millisecond of the time period.
 332:      *
 333:      * @param calendar  the calendar.
 334:      *
 335:      * @return The last millisecond of the time period.
 336:      */
 337:     public long getLastMillisecond(Calendar calendar) {
 338:         return this.second.getFirstMillisecond(calendar) + this.millisecond;
 339:     }
 340: 
 341: }