Home » commons-lang-2.4-src » org.apache.commons » lang » time » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.commons.lang.time;
   19   
   20   /**
   21    * <p>
   22    * <code>StopWatch</code> provides a convenient API for timings.
   23    * </p>
   24    * 
   25    * <p>
   26    * To start the watch, call {@link #start()}. At this point you can:
   27    * </p>
   28    * <ul>
   29    * <li>{@link #split()} the watch to get the time whilst the watch continues in the background. {@link #unsplit()} will
   30    * remove the effect of the split. At this point, these three options are available again.</li>
   31    * <li>{@link #suspend()} the watch to pause it. {@link #resume()} allows the watch to continue. Any time between the
   32    * suspend and resume will not be counted in the total. At this point, these three options are available again.</li>
   33    * <li>{@link #stop()} the watch to complete the timing session.</li>
   34    * </ul>
   35    * 
   36    * <p>
   37    * It is intended that the output methods {@link #toString()} and {@link #getTime()} should only be called after stop,
   38    * split or suspend, however a suitable result will be returned at other points.
   39    * </p>
   40    * 
   41    * <p>
   42    * NOTE: As from v2.1, the methods protect against inappropriate calls. Thus you cannot now call stop before start,
   43    * resume before suspend or unsplit before split.
   44    * </p>
   45    * 
   46    * <p>
   47    * 1. split(), suspend(), or stop() cannot be invoked twice<br />
   48    * 2. unsplit() may only be called if the watch has been split()<br />
   49    * 3. resume() may only be called if the watch has been suspend()<br />
   50    * 4. start() cannot be called twice without calling reset()
   51    * </p>
   52    * 
   53    * @author Stephen Colebourne
   54    * @since 2.0
   55    * @version $Id: StopWatch.java 583608 2007-10-10 20:38:41Z ggregory $
   56    */
   57   public class StopWatch {
   58   
   59       // running states
   60       private static final int STATE_UNSTARTED = 0;
   61   
   62       private static final int STATE_RUNNING = 1;
   63   
   64       private static final int STATE_STOPPED = 2;
   65   
   66       private static final int STATE_SUSPENDED = 3;
   67   
   68       // split state
   69       private static final int STATE_UNSPLIT = 10;
   70   
   71       private static final int STATE_SPLIT = 11;
   72   
   73       /**
   74        * The current running state of the StopWatch.
   75        */
   76       private int runningState = STATE_UNSTARTED;
   77   
   78       /**
   79        * Whether the stopwatch has a split time recorded.
   80        */
   81       private int splitState = STATE_UNSPLIT;
   82   
   83       /**
   84        * The start time.
   85        */
   86       private long startTime = -1;
   87   
   88       /**
   89        * The stop time.
   90        */
   91       private long stopTime = -1;
   92   
   93       /**
   94        * <p>
   95        * Constructor.
   96        * </p>
   97        */
   98       public StopWatch() {
   99           super();
  100       }
  101   
  102       /**
  103        * <p>
  104        * Start the stopwatch.
  105        * </p>
  106        * 
  107        * <p>
  108        * This method starts a new timing session, clearing any previous values.
  109        * </p>
  110        * 
  111        * @throws IllegalStateException
  112        *             if the StopWatch is already running.
  113        */
  114       public void start() {
  115           if (this.runningState == STATE_STOPPED) {
  116               throw new IllegalStateException("Stopwatch must be reset before being restarted. ");
  117           }
  118           if (this.runningState != STATE_UNSTARTED) {
  119               throw new IllegalStateException("Stopwatch already started. ");
  120           }
  121           this.stopTime = -1;
  122           this.startTime = System.currentTimeMillis();
  123           this.runningState = STATE_RUNNING;
  124       }
  125   
  126       /**
  127        * <p>
  128        * Stop the stopwatch.
  129        * </p>
  130        * 
  131        * <p>
  132        * This method ends a new timing session, allowing the time to be retrieved.
  133        * </p>
  134        * 
  135        * @throws IllegalStateException
  136        *             if the StopWatch is not running.
  137        */
  138       public void stop() {
  139           if (this.runningState != STATE_RUNNING && this.runningState != STATE_SUSPENDED) {
  140               throw new IllegalStateException("Stopwatch is not running. ");
  141           }
  142           if (this.runningState == STATE_RUNNING) {
  143               this.stopTime = System.currentTimeMillis();
  144           }
  145           this.runningState = STATE_STOPPED;
  146       }
  147   
  148       /**
  149        * <p>
  150        * Resets the stopwatch. Stops it if need be.
  151        * </p>
  152        * 
  153        * <p>
  154        * This method clears the internal values to allow the object to be reused.
  155        * </p>
  156        */
  157       public void reset() {
  158           this.runningState = STATE_UNSTARTED;
  159           this.splitState = STATE_UNSPLIT;
  160           this.startTime = -1;
  161           this.stopTime = -1;
  162       }
  163   
  164       /**
  165        * <p>
  166        * Split the time.
  167        * </p>
  168        * 
  169        * <p>
  170        * This method sets the stop time of the watch to allow a time to be extracted. The start time is unaffected,
  171        * enabling {@link #unsplit()} to continue the timing from the original start point.
  172        * </p>
  173        * 
  174        * @throws IllegalStateException
  175        *             if the StopWatch is not running.
  176        */
  177       public void split() {
  178           if (this.runningState != STATE_RUNNING) {
  179               throw new IllegalStateException("Stopwatch is not running. ");
  180           }
  181           this.stopTime = System.currentTimeMillis();
  182           this.splitState = STATE_SPLIT;
  183       }
  184   
  185       /**
  186        * <p>
  187        * Remove a split.
  188        * </p>
  189        * 
  190        * <p>
  191        * This method clears the stop time. The start time is unaffected, enabling timing from the original start point to
  192        * continue.
  193        * </p>
  194        * 
  195        * @throws IllegalStateException
  196        *             if the StopWatch has not been split.
  197        */
  198       public void unsplit() {
  199           if (this.splitState != STATE_SPLIT) {
  200               throw new IllegalStateException("Stopwatch has not been split. ");
  201           }
  202           this.stopTime = -1;
  203           this.splitState = STATE_UNSPLIT;
  204       }
  205   
  206       /**
  207        * <p>
  208        * Suspend the stopwatch for later resumption.
  209        * </p>
  210        * 
  211        * <p>
  212        * This method suspends the watch until it is resumed. The watch will not include time between the suspend and
  213        * resume calls in the total time.
  214        * </p>
  215        * 
  216        * @throws IllegalStateException
  217        *             if the StopWatch is not currently running.
  218        */
  219       public void suspend() {
  220           if (this.runningState != STATE_RUNNING) {
  221               throw new IllegalStateException("Stopwatch must be running to suspend. ");
  222           }
  223           this.stopTime = System.currentTimeMillis();
  224           this.runningState = STATE_SUSPENDED;
  225       }
  226   
  227       /**
  228        * <p>
  229        * Resume the stopwatch after a suspend.
  230        * </p>
  231        * 
  232        * <p>
  233        * This method resumes the watch after it was suspended. The watch will not include time between the suspend and
  234        * resume calls in the total time.
  235        * </p>
  236        * 
  237        * @throws IllegalStateException
  238        *             if the StopWatch has not been suspended.
  239        */
  240       public void resume() {
  241           if (this.runningState != STATE_SUSPENDED) {
  242               throw new IllegalStateException("Stopwatch must be suspended to resume. ");
  243           }
  244           this.startTime += (System.currentTimeMillis() - this.stopTime);
  245           this.stopTime = -1;
  246           this.runningState = STATE_RUNNING;
  247       }
  248   
  249       /**
  250        * <p>
  251        * Get the time on the stopwatch.
  252        * </p>
  253        * 
  254        * <p>
  255        * This is either the time between the start and the moment this method is called, or the amount of time between
  256        * start and stop.
  257        * </p>
  258        * 
  259        * @return the time in milliseconds
  260        */
  261       public long getTime() {
  262           if (this.runningState == STATE_STOPPED || this.runningState == STATE_SUSPENDED) {
  263               return this.stopTime - this.startTime;
  264           } else if (this.runningState == STATE_UNSTARTED) {
  265               return 0;
  266           } else if (this.runningState == STATE_RUNNING) {
  267               return System.currentTimeMillis() - this.startTime;
  268           }
  269           throw new RuntimeException("Illegal running state has occured. ");
  270       }
  271   
  272       /**
  273        * <p>
  274        * Get the split time on the stopwatch.
  275        * </p>
  276        * 
  277        * <p>
  278        * This is the time between start and latest split.
  279        * </p>
  280        * 
  281        * @return the split time in milliseconds
  282        * 
  283        * @throws IllegalStateException
  284        *             if the StopWatch has not yet been split.
  285        * @since 2.1
  286        */
  287       public long getSplitTime() {
  288           if (this.splitState != STATE_SPLIT) {
  289               throw new IllegalStateException("Stopwatch must be split to get the split time. ");
  290           }
  291           return this.stopTime - this.startTime;
  292       }
  293   
  294       /**
  295        * Returns the time this stopwatch was started.
  296        * 
  297        * @return the time this stopwatch was started
  298        * @throws IllegalStateException
  299        *             if this StopWatch has not been started
  300        * @since 2.4
  301        */
  302       public long getStartTime() {
  303           if (this.runningState == STATE_UNSTARTED) {
  304               throw new IllegalStateException("Stopwatch has not been started");
  305           }
  306           return this.startTime;
  307       }
  308   
  309       /**
  310        * <p>
  311        * Gets a summary of the time that the stopwatch recorded as a string.
  312        * </p>
  313        * 
  314        * <p>
  315        * The format used is ISO8601-like, <i>hours</i>:<i>minutes</i>:<i>seconds</i>.<i>milliseconds</i>.
  316        * </p>
  317        * 
  318        * @return the time as a String
  319        */
  320       public String toString() {
  321           return DurationFormatUtils.formatDurationHMS(getTime());
  322       }
  323   
  324       /**
  325        * <p>
  326        * Gets a summary of the split time that the stopwatch recorded as a string.
  327        * </p>
  328        * 
  329        * <p>
  330        * The format used is ISO8601-like, <i>hours</i>:<i>minutes</i>:<i>seconds</i>.<i>milliseconds</i>.
  331        * </p>
  332        * 
  333        * @return the split time as a String
  334        * @since 2.1
  335        */
  336       public String toSplitString() {
  337           return DurationFormatUtils.formatDurationHMS(getSplitTime());
  338       }
  339   
  340   }

Save This Page
Home » commons-lang-2.4-src » org.apache.commons » lang » time » [javadoc | source]