1. /* ====================================================================
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if
  20. * any, must include the following acknowledgement:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowledgement may appear in the software itself,
  24. * if and wherever such third-party acknowledgements normally appear.
  25. *
  26. * 4. The names "The Jakarta Project", "Commons", and "Apache Software
  27. * Foundation" must not be used to endorse or promote products derived
  28. * from this software without prior written permission. For written
  29. * permission, please contact apache@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache"
  32. * nor may "Apache" appear in their names without prior written
  33. * permission of the Apache Software Foundation.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation. For more
  51. * information on the Apache Software Foundation, please see
  52. * <http://www.apache.org/>.
  53. */
  54. package org.apache.commons.lang.time;
  55. /**
  56. * <p><code>StopWatch</code> provides a convenient API for timings.</p>
  57. *
  58. * <p>The methods do <b>not</b> protect against inappropriate calls. Thus you
  59. * can call stop before start, resume before suspend or unsplit before split.
  60. * The results are indeterminate in these cases.</p>
  61. *
  62. * <p>To start the watch, call {@link #start()}. At this point you can:</p>
  63. * <ul>
  64. * <li>{@link #split()} the watch to get the time whilst the watch continues in the
  65. * background. {@link #unsplit()} will remove the effect of the split. At this point,
  66. * these three options are available again.</li>
  67. * <li>{@link #suspend()} the watch to pause it. {@link #resume()} allows the watch
  68. * to continue. Any time between the suspend and resume will not be counted in
  69. * the total. At this point, these three options are available again.</li>
  70. * <li>{@link #stop()} the watch to complete the timing session.</li>
  71. * </ul>
  72. *
  73. * <p>It is intended that the output methods {@link #toString()} and {@link #getTime()}
  74. * should only be called after stop, split or suspend, however a suitable result will
  75. * be returned at other points.</p>
  76. *
  77. * @author Henri Yandell
  78. * @author Stephen Colebourne
  79. * @since 2.0
  80. * @version $Id: StopWatch.java,v 1.6 2003/08/18 02:22:25 bayard Exp $
  81. */
  82. public class StopWatch {
  83. /**
  84. * The start time.
  85. */
  86. private long startTime = -1;
  87. /**
  88. * The stop time.
  89. */
  90. private long stopTime = -1;
  91. /**
  92. * <p>Constructor.</p>
  93. */
  94. public StopWatch() {
  95. }
  96. /**
  97. * <p>Start the stopwatch.</p>
  98. *
  99. * <p>This method starts a new timing session, clearing any previous values.</p>
  100. */
  101. public void start() {
  102. stopTime = -1;
  103. startTime = System.currentTimeMillis();
  104. }
  105. /**
  106. * <p>Stop the stopwatch.</p>
  107. *
  108. * <p>This method ends a new timing session, allowing the time to be retrieved.</p>
  109. */
  110. public void stop() {
  111. stopTime = System.currentTimeMillis();
  112. }
  113. /**
  114. * <p>Reset the stopwatch.</p>
  115. *
  116. * <p>This method clears the internal values to allow the object to be reused.</p>
  117. */
  118. public void reset() {
  119. startTime = -1;
  120. stopTime = -1;
  121. }
  122. /**
  123. * <p>Split the time.</p>
  124. *
  125. * <p>This method sets the stop time of the watch to allow a time to be extracted.
  126. * The start time is unaffected, enabling {@link #unsplit()} to contine the
  127. * timing from the original start point.</p>
  128. */
  129. public void split() {
  130. stopTime = System.currentTimeMillis();
  131. }
  132. /**
  133. * <p>Remove a split.</p>
  134. *
  135. * <p>This method clears the stop time. The start time is unaffected, enabling
  136. * timing from the original start point to continue.</p>
  137. */
  138. public void unsplit() {
  139. stopTime = -1;
  140. }
  141. /**
  142. * <p>Suspend the stopwatch for later resumption.</p>
  143. *
  144. * <p>This method suspends the watch until it is resumed. The watch will not include
  145. * time between the suspend and resume calls in the total time.</p>
  146. */
  147. public void suspend() {
  148. stopTime = System.currentTimeMillis();
  149. }
  150. /**
  151. * <p>Resume the stopwatch after a suspend.</p>
  152. *
  153. * <p>This method resumes the watch after it was suspended. The watch will not include
  154. * time between the suspend and resume calls in the total time.</p>
  155. */
  156. public void resume() {
  157. startTime += (System.currentTimeMillis() - stopTime);
  158. stopTime = -1;
  159. }
  160. /**
  161. * <p>Get the time on the stopwatch.</p>
  162. *
  163. * <p>This is either the time between start and latest split, between start
  164. * and stop, or the time between the start and the moment this method is called.</p>
  165. *
  166. * @return the time in milliseconds
  167. */
  168. public long getTime() {
  169. if (stopTime == -1) {
  170. if (startTime == -1) {
  171. return 0;
  172. }
  173. return (System.currentTimeMillis() - this.startTime);
  174. }
  175. return (this.stopTime - this.startTime);
  176. }
  177. /**
  178. * <p>Gets a summary of the time that the stopwatch recorded as a string.</p>
  179. *
  180. * <p>The format used is ISO8601-like,
  181. * <i>hours</i>:<i>minutes</i>:<i>seconds</i>.<i>milliseconds</i>.</p>
  182. *
  183. * @return the time as a String
  184. */
  185. public String toString() {
  186. return DurationFormatUtils.formatISO(getTime());
  187. }
  188. }