Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.util; 027 028import java.io.Serializable; 029 030/** 031 * <p> 032 * A class that defines a duration of time. Duration instances are immutable, 033 * and are therefore replaced rather than modified, similar to {@link java.math.BigDecimal}. 034 * Duration's can be created using the constructor, or one of the static construction 035 * methods such as {@link #seconds} or {@link #minutes}. 036 * </p> 037 */ 038public class Duration implements Comparable<Duration>, Serializable { 039 /** 040 * A Duration of 0 (no time). 041 */ 042 public static final Duration ZERO = new Duration(0); 043 044 /** 045 * A Duration of 1 millisecond. 046 */ 047 public static final Duration ONE = new Duration(1); 048 049 /** 050 * An Infinite Duration. 051 */ 052 public static final Duration INDEFINITE = new Duration(Double.POSITIVE_INFINITY); 053 054 /** 055 * A Duration of some unknown amount of time. 056 */ 057 public static final Duration UNKNOWN = new Duration(Double.NaN); 058 059 /** 060 * Factory method that returns a Duration instance for a specified 061 * amount of time. The syntax is "[number][ms|s|m|h]". 062 * 063 * @param time A non-null string properly formatted. Leading or trailing 064 * spaces will not parse correctly. Throws a NullPointerException if 065 * time is null. 066 * @return a Duration which is represented by the <code>time</code> 067 */ 068 public static Duration valueOf(String time) { 069 int index = -1; 070 for (int i=0; i<time.length(); i++) { 071 char c = time.charAt(i); 072 if (!Character.isDigit(c) && c != '.' && c != '-') { 073 index = i; 074 break; 075 } 076 } 077 078 if (index == -1) { 079 // Never found the suffix! 080 throw new IllegalArgumentException("The time parameter must have a suffix of [ms|s|m|h]"); 081 } 082 083 double value = Double.parseDouble(time.substring(0, index)); 084 String suffix = time.substring(index); 085 if ("ms".equals(suffix)) { 086 return millis(value); 087 } else if ("s".equals(suffix)) { 088 return seconds(value); 089 } else if ("m".equals(suffix)) { 090 return minutes(value); 091 } else if ("h".equals(suffix)) { 092 return hours(value); 093 } else { 094 // Malformed suffix 095 throw new IllegalArgumentException("The time parameter must have a suffix of [ms|s|m|h]"); 096 } 097 } 098 099 /** 100 * Factory method that returns a Duration instance for a specified 101 * number of milliseconds. 102 * 103 * @param ms the number of milliseconds 104 * @return a Duration instance of the specified number of milliseconds 105 */ 106 public static Duration millis(double ms) { 107 if (ms == 0) { 108 return ZERO; 109 } else if (ms == 1) { 110 return ONE; 111 } else if (ms == Double.POSITIVE_INFINITY) { 112 return INDEFINITE; 113 } else if (Double.isNaN(ms)) { 114 return UNKNOWN; 115 } else { 116 return new Duration(ms); 117 } 118 } 119 120 /** 121 * Factory method that returns a Duration instance representing the specified 122 * number of seconds. 123 * 124 * @param s the number of seconds 125 * @return a Duration instance of the specified number of seconds 126 */ 127 public static Duration seconds(double s) { 128 if (s == 0) { 129 return ZERO; 130 } else if (s == Double.POSITIVE_INFINITY) { 131 return INDEFINITE; 132 } else if (Double.isNaN(s)) { 133 return UNKNOWN; 134 } else { 135 return new Duration(s * 1000.0); 136 } 137 } 138 139 /** 140 * Factory method that returns a Duration instance representing the specified 141 * number of minutes. 142 * 143 * @param m the number of minutes 144 * @return a Duration instance of the specified number of minutes 145 */ 146 public static Duration minutes(double m) { 147 if (m == 0) { 148 return ZERO; 149 } else if (m == Double.POSITIVE_INFINITY) { 150 return INDEFINITE; 151 } else if (Double.isNaN(m)) { 152 return UNKNOWN; 153 } else { 154 return new Duration(m * (1000.0 * 60.0)); 155 } 156 } 157 158 /** 159 * Factory method that returns a Duration instance representing the specified 160 * number of hours. 161 * 162 * @param h the number of hours 163 * @return a Duration instance representing the specified number of hours 164 */ 165 public static Duration hours(double h) { 166 if (h == 0) { 167 return ZERO; 168 } else if (h == Double.POSITIVE_INFINITY) { 169 return INDEFINITE; 170 } else if (Double.isNaN(h)) { 171 return UNKNOWN; 172 } else { 173 return new Duration(h * (1000.0 * 60.0 * 60.0)); 174 } 175 } 176 177 /** 178 * The value of this duration, in fractional milliseconds 179 */ 180 private final double millis; 181 182 /** 183 * Creates a new Duration with potentially fractional millisecond resolution. 184 * @param millis The number of milliseconds 185 */ 186 public Duration(double millis) { 187 this.millis = millis; 188 } 189 190 /** 191 * Returns the number of milliseconds in this period or Double.POSITIVE_INFINITY 192 * if the period is INDEFINITE or NaN if the period is UNKNOWN. 193 * @return the Duration in fractional milliseconds 194 */ 195 public double toMillis() { 196 return millis; 197 } 198 199 /** 200 * Returns the number of seconds in this period or Double.POSITIVE_INFINITY 201 * if the period is INDEFINITE or NaN if the period is UNKNOWN. 202 * @return the Duration in fractional seconds 203 */ 204 public double toSeconds() { 205 return millis / 1000.0; 206 } 207 208 /** 209 * Returns the number of minutes in this period or Double.POSITIVE_INFINITY 210 * if the period is INDEFINITE or NaN if the period is UNKNOWN. 211 * @return the Duration in fractional minutes 212 */ 213 public double toMinutes() { 214 return millis / (60 * 1000.0); 215 } 216 217 /** 218 * Returns the number of hours in this period or Double.POSITIVE_INFINITY 219 * if the period is INDEFINITE or NaN if the period is UNKNOWN. 220 * @return the Duration in fractional hours 221 */ 222 public double toHours() { 223 return millis / (60 * 60 * 1000.0); 224 } 225 226 /** 227 * Add this instance and another Duration instance to return a new Duration instance. 228 * If either instance is INDEFINITE, return INDEFINITE. 229 * If either instance is UNKNOWN, return UNKNOWN. 230 * This method does not change the value of the called Duration instance. 231 * 232 * @param other must not be null 233 * @return the result of adding this duration to the other duration. This is 234 * the same as millis + other.millis using double arithmetic 235 */ 236 public Duration add(Duration other) { 237 // Note that several of these functions assume that the value of millis in INDEFINITE 238 // is Double.POSITIVE_INFINITY. 239 return millis(millis + other.millis); 240 } 241 242 /** 243 * Subtract other Duration instance from this instance to return a new Duration instance. 244 * If either instance is UNKNOWN, return UNKNOWN. 245 * Otherwise, if either instance is INDEFINITE, return INDEFINITE. 246 * This method does not change the value of the called Duration instance. 247 * 248 * @param other must not be null 249 * @return the result of subtracting the other duration from this duration. This is 250 * the same as millis - other.millis using double arithmetic 251 */ 252 public Duration subtract(Duration other) { 253 return millis(millis - other.millis); 254 } 255 256 /** 257 * Multiply this instance with a number to return a new Duration instance. 258 * If either instance is INDEFINITE, return INDEFINITE. 259 * If either Duration instance is UNKNOWN, return UNKNOWN. 260 * This method does not change the value of the called Duration instance. 261 * 262 * @deprecated This method produces surprising results by not taking units into 263 * account. Use {@link #multiply(double)} instead. 264 * @param other must not be null 265 * @return the result of multiplying this duration with the other duration. This is 266 * the same as millis * other.millis using double arithmetic 267 */ 268 @Deprecated 269 public Duration multiply(Duration other) { 270 return millis(millis * other.millis); 271 } 272 273 /** 274 * Multiply this instance with a number representing millis and return a new Duration. 275 * If the called Duration instance is INDEFINITE, return INDEFINITE. 276 * If the called Duration instance is UNKNOWN, return UNKNOWN. 277 * This method does not change the value of the called Duration instance. 278 * 279 * @param n the amount to multiply by in fractional milliseconds 280 * @return the result of multiplying this duration with n. This is 281 * the same as millis * n using double arithmetic 282 */ 283 public Duration multiply(double n) { 284 return millis(millis * n); 285 } 286 287 /** 288 * Divide this instance by a number to return a new Duration instance. 289 * If the called Duration instance is INDEFINITE, return INDEFINITE. 290 * If the called Duration instance is UNKNOWN, return UNKNOWN. 291 * This method does not change the value of the called Duration instance. 292 * 293 * @param n the amount to divide by in fractional milliseconds 294 * @return the result of dividing this duration with n. This is 295 * the same as millis / n using double arithmetic 296 */ 297 public Duration divide(double n) { 298 return millis(millis / n); 299 } 300 301 /** 302 * Divide this instance by another Duration to return the ratio. 303 * If both instances are INDEFINITE, return NaN. 304 * If this instance is INDEFINITE, return POSITIVE_INFINITY 305 * If the other instance is INDEFINITE, return 0.0. 306 * This function does not change the value of the called Duration instance. 307 * 308 * @deprecated This method produces surprising results by not taking units into 309 * account. Use {@link #divide(double)} instead. 310 * @param other must not be null 311 * @return the result of dividing this duration by the other duration. This is 312 * the same as millis / other.millis using double arithmetic 313 */ 314 @Deprecated 315 public Duration divide(Duration other) { 316 return millis(millis / other.millis); 317 } 318 319 /** 320 * Return a new Duration instance which has a negative number of milliseconds 321 * from this instance. For example, <code>Duration.millis(50).negate()</code> returns 322 * a Duration of -50 milliseconds. 323 * If the called Duration instance is INDEFINITE, return INDEFINITE. 324 * This function does not change the value of the called Duration instance. 325 * 326 * @return the result of negating this duration. This is 327 * the same as -millis using double arithmetic 328 */ 329 public Duration negate() { 330 return millis(-millis); 331 } 332 333 /** 334 * Gets whether this Duration instance is Indefinite. A Duration is Indefinite 335 * if it equals Duration.INDEFINITE. 336 * @return true if this Duration is equivalent to Duration.INDEFINITE or Double.POSITIVE_INFINITY. 337 */ 338 public boolean isIndefinite() { 339 return millis == Double.POSITIVE_INFINITY; 340 } 341 342 /** 343 * Gets whether this Duration instance is Unknown. A Duration is Unknown 344 * if it equals Duration.UNKNOWN. 345 * @return true if this Duration is equivalent to Duration.UNKNOWN or Double.isNaN(millis) 346 */ 347 public boolean isUnknown() { 348 return Double.isNaN(millis); 349 } 350 351 /** 352 * Returns true if the specified duration is less than (<) this instance. 353 * INDEFINITE is treated as if it were positive infinity. 354 * 355 * @param other cannot be null 356 * @return true if millis < other.millis using double arithmetic 357 */ 358 public boolean lessThan(Duration other) { 359 return millis < other.millis; 360 } 361 362 /** 363 * Returns true if the specified duration is less than or equal to (<=) this instance. 364 * INDEFINITE is treated as if it were positive infinity. 365 * 366 * @param other cannot be null 367 * @return true if millis <= other.millis using double arithmetic 368 */ 369 public boolean lessThanOrEqualTo(Duration other) { 370 return millis <= other.millis; 371 } 372 373 /** 374 * Returns true if the specified duration is greater than (>) this instance. 375 * INDEFINITE is treated as if it were positive infinity. 376 * 377 * @param other cannot be null 378 * @return true if millis > other.millis using double arithmetic 379 */ 380 public boolean greaterThan(Duration other) { 381 return millis > other.millis; 382 } 383 384 /** 385 * Returns true if the specified duration is greater than or equal to (>=) this instance. 386 * INDEFINITE is treated as if it were positive infinity. 387 * 388 * @param other cannot be null 389 * @return true if millis >= other.millis using double arithmetic 390 */ 391 public boolean greaterThanOrEqualTo(Duration other) { 392 return millis >= other.millis; 393 } 394 395 /** 396 * Returns a string representation of this {@code Duration} object. 397 * @return a string representation of this {@code Duration} object. 398 */ 399 @Override public String toString() { 400 return isIndefinite() ? "INDEFINITE" : (isUnknown() ? "UNKNOWN" : millis + " ms"); 401 } 402 403 /** 404 * Compares durations represented by this object and the specified object. 405 * Returns a negative integer, zero, or a positive integer as this duration 406 * is less than, equal to, or greater than the specified duration. 407 * @param d the duration to be compared. 408 * @return a negative integer, zero, or a positive integer as this duration 409 * is less than, equal to, or greater than the specified duration. 410 */ 411 @Override public int compareTo(Duration d) { 412 // Reuse the Double.compare implementation 413 return Double.compare(millis, d.millis); 414 } 415 416 /** 417 * Indicates whether some other object is "equal to" this one. 418 * @param obj the reference object with which to compare. 419 * @return {@code true} if this object is equal to the {@code obj} argument; {@code false} otherwise. 420 */ 421 @Override public boolean equals(Object obj) { 422 // Rely on Java's handling of double == double 423 return obj == this || obj instanceof Duration && millis == ((Duration) obj).millis; 424 } 425 426 /** 427 * Returns a hash code for this {@code Duration} object. 428 * @return a hash code for this {@code Duration} object. 429 */ 430 @Override public int hashCode() { 431 // Uses the same implementation as Double.hashCode 432 long bits = Double.doubleToLongBits(millis); 433 return (int)(bits ^ (bits >>> 32)); 434 } 435}