001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jfreechart/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 025 * in the United States and other countries.] 026 * 027 * ---------------- 028 * Millisecond.java 029 * ---------------- 030 * (C) Copyright 2001-2005, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * $Id: Millisecond.java,v 1.5.2.1 2005/10/25 21:35:24 mungady Exp $ 036 * 037 * Changes 038 * ------- 039 * 11-Oct-2001 : Version 1 (DG); 040 * 19-Dec-2001 : Added new constructors as suggested by Paul English (DG); 041 * 26-Feb-2002 : Added new getStart() and getEnd() methods (DG); 042 * 29-Mar-2002 : Fixed bug in getStart(), getEnd() and compareTo() methods (DG); 043 * 10-Sep-2002 : Added getSerialIndex() method (DG); 044 * 07-Oct-2002 : Fixed errors reported by Checkstyle (DG); 045 * 10-Jan-2003 : Changed base class and method names (DG); 046 * 13-Mar-2003 : Moved to com.jrefinery.data.time package and implemented 047 * Serializable (DG); 048 * 21-Oct-2003 : Added hashCode() method (DG); 049 * 050 */ 051 052 package org.jfree.data.time; 053 054 import java.io.Serializable; 055 import java.util.Calendar; 056 import java.util.Date; 057 import java.util.TimeZone; 058 059 /** 060 * Represents a millisecond. This class is immutable, which is a requirement 061 * for all {@link RegularTimePeriod} subclasses. 062 */ 063 public class Millisecond extends RegularTimePeriod implements Serializable { 064 065 /** For serialization. */ 066 static final long serialVersionUID = -5316836467277638485L; 067 068 /** A constant for the first millisecond in a second. */ 069 public static final int FIRST_MILLISECOND_IN_SECOND = 0; 070 071 /** A constant for the last millisecond in a second. */ 072 public static final int LAST_MILLISECOND_IN_SECOND = 999; 073 074 /** The millisecond. */ 075 private int millisecond; 076 077 /** The second. */ 078 private Second second; 079 080 /** 081 * Constructs a millisecond based on the current system time. 082 */ 083 public Millisecond() { 084 this(new Date()); 085 } 086 087 /** 088 * Constructs a millisecond. 089 * 090 * @param millisecond the millisecond (0-999). 091 * @param second the second. 092 */ 093 public Millisecond(int millisecond, Second second) { 094 this.millisecond = millisecond; 095 this.second = second; 096 } 097 098 /** 099 * 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 }