| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.uima.internal.util; |
| |
| /** |
| * Encode a span of time. The main purpose of this class is to provide a printing utility for time |
| * spans. E.g., 1081 ms should be printed as 1.081 s, 108101 ms should be printed as 1 min 48.101 s, |
| * etc. |
| * <p> |
| * |
| * Note that the largest value you can represent with this class is 9223372036854775807 (<code>Long.MAX_VALUE</code>), |
| * or equivalently, 292471208 yrs 247 days 7 hrs 12 min 55.807 sec. Overflow is not handled |
| * gracefully by this class. |
| * <p> |
| * |
| * Also note that for the purposes of this class, a year has 365 days. I.e., a year corresponds to |
| * <code>365 * 24 * 60 * 60 * 1000</code> ms. |
| */ |
| public class TimeSpan { |
| |
| private long all; |
| |
| private int years; |
| |
| private int days; |
| |
| private int hours; |
| |
| private int minutes; |
| |
| private int seconds; |
| |
| private int milliseconds; |
| |
| private boolean knowsFull = false; |
| |
| private boolean knowsMS = false; |
| |
| private static final long msSecond = 1000; |
| |
| private static final long msMinute = msSecond * 60; |
| |
| private static final long msHour = msMinute * 60; |
| |
| private static final long msDay = msHour * 24; |
| |
| private static final long msYear = msDay * 365; |
| |
| private static final String yearsString = "yrs"; |
| |
| private static final String daysString = "days"; |
| |
| private static final String hoursString = "hrs"; |
| |
| private static final String minutesString = "min"; |
| |
| private static final String secondsString = "sec"; |
| |
| private static final String msString = "ms"; |
| |
| private static final String unknownTime = "unknown"; |
| |
| /** |
| * Create an uninstantiated <code>TimeSpan</code>. |
| */ |
| public TimeSpan() { |
| super(); |
| } |
| |
| /** |
| * Create a <code>TimeSpan</code> from a ms interval. |
| * |
| * @param milliseconds |
| * The interval in ms. If <code>milliseconds |
| < 0</code>, an uninstantiated |
| * <code>TimeSpan</code> is created. |
| */ |
| public TimeSpan(long milliseconds) { |
| if (milliseconds >= 0) { |
| this.all = milliseconds; |
| this.knowsMS = true; |
| } |
| } |
| |
| /** |
| * @return <code>true</code>, if the object has been instantiated with a legal interval; |
| * <code>false</code>, else. |
| */ |
| public boolean isInstantiated() { |
| return (this.knowsMS || this.knowsFull); |
| } |
| |
| /** |
| * Set the year fraction of this <code>TimeSpan</code>. |
| * |
| * @param years |
| * The number of years. |
| * @return <code>false</code>, if <code>years < 0</code>; <code>true</code>, else. |
| */ |
| public boolean setYears(int years) { |
| if (years < 0) { |
| return false; |
| } |
| this.years = years; |
| this.knowsFull = true; |
| this.knowsMS = false; |
| return true; |
| } |
| |
| /** |
| * Set the day fraction of this <code>TimeSpan</code>. |
| * |
| * @param days |
| * The number of days. |
| * @return <code>false</code>, if <code>days < 0</code>; <code>true</code>, else. |
| */ |
| public boolean setDays(int days) { |
| if (days < 0) { |
| return false; |
| } |
| this.days = days; |
| this.knowsFull = true; |
| this.knowsMS = false; |
| return true; |
| } |
| |
| /** |
| * Set the hour fraction of this <code>TimeSpan</code>. |
| * |
| * @param hours |
| * The number of hours. |
| * @return <code>false</code>, if <code>hours < 0</code>; <code>true</code>, else. |
| */ |
| public boolean setHours(int hours) { |
| if (hours < 0) { |
| return false; |
| } |
| this.hours = hours; |
| this.knowsFull = true; |
| this.knowsMS = false; |
| return true; |
| } |
| |
| /** |
| * Set the minute fraction of this <code>TimeSpan</code>. |
| * |
| * @param minutes |
| * The number of minutes. |
| * @return <code>false</code>, if <code>minutes < 0</code>; <code>true</code>, else. |
| */ |
| public boolean setMinutes(int minutes) { |
| if (minutes < 0) { |
| return false; |
| } |
| this.minutes = minutes; |
| this.knowsFull = true; |
| this.knowsMS = false; |
| return true; |
| } |
| |
| /** |
| * Set the second fraction of this <code>TimeSpan</code>. |
| * |
| * @param seconds |
| * The number of seconds. |
| * @return <code>false</code>, if <code>seconds < 0</code>; <code>true</code>, else. |
| */ |
| public boolean setSeconds(int seconds) { |
| if (seconds < 0) { |
| return false; |
| } |
| this.seconds = seconds; |
| this.knowsFull = true; |
| this.knowsMS = false; |
| return true; |
| } |
| |
| /** |
| * Set the millisecond fraction of this <code>TimeSpan</code>. |
| * |
| * @param milliseconds |
| * The number of milliseconds. |
| * @return <code>false</code>, if <code>milliseconds < 0</code>; <code>true</code>, |
| * else. |
| */ |
| public boolean setMilliseconds(int milliseconds) { |
| if (milliseconds < 0) { |
| return false; |
| } |
| this.milliseconds = milliseconds; |
| this.knowsFull = true; |
| this.knowsMS = false; |
| return true; |
| } |
| |
| /** |
| * Set the full <code>TimeSpan</code> in terms of milliseconds. |
| * |
| * @param milliseconds |
| * The number of milliseconds. |
| * @return <code>false</code>, if <code>milliseconds < 0</code>; <code>true</code>, |
| * else. |
| */ |
| public boolean setFullMilliseconds(long milliseconds) { |
| if (milliseconds < 0) { |
| return false; |
| } |
| this.all = milliseconds; |
| this.knowsMS = true; |
| this.knowsFull = false; |
| return true; |
| } |
| |
| /** |
| * Get the length of the <code>TimeSpan</code> as milliseconds. |
| * |
| * @return The number of milliseconds, if known. <code>-1</code>, else (e.g., when the |
| * <code>TimeSpan</code> is not instantiated). |
| */ |
| public long getFullMilliseconds() { |
| ensureAll(); |
| if (!this.knowsMS) { |
| return -1; |
| } |
| return this.all; |
| } |
| |
| /** |
| * Get the year fraction of this object. |
| * |
| * @return <code>-1</code>, if this object is not instantiated; the year fraction, else. |
| */ |
| public int getYears() { |
| ensureFull(); |
| return this.isInstantiated() ? this.years : -1; |
| } |
| |
| /** |
| * Get the day fraction of this object. |
| * |
| * @return <code>-1</code>, if this object is not instantiated; the day fraction, else. |
| */ |
| public int getDays() { |
| ensureFull(); |
| return this.isInstantiated() ? this.days : -1; |
| } |
| |
| /** |
| * Get the hour fraction of this object. |
| * |
| * @return <code>-1</code>, if this object is not instantiated; the hour fraction, else. |
| */ |
| public int getHours() { |
| ensureFull(); |
| return this.isInstantiated() ? this.hours : -1; |
| } |
| |
| /** |
| * Get the minute fraction of this object. |
| * |
| * @return <code>-1</code>, if this object is not instantiated; the minute fraction, else. |
| */ |
| public int getMinutes() { |
| ensureFull(); |
| return this.isInstantiated() ? this.minutes : -1; |
| } |
| |
| /** |
| * Get the second fraction of this object. |
| * |
| * @return <code>-1</code>, if this object is not instantiated; the second fraction, else. |
| */ |
| public int getSeconds() { |
| ensureFull(); |
| return this.isInstantiated() ? this.seconds : -1; |
| } |
| |
| /** |
| * Get the millisecond fraction of this object. |
| * |
| * @return <code>-1</code>, if this object is not instantiated; the millisecond fraction, else. |
| */ |
| public int getMilliseconds() { |
| ensureFull(); |
| return this.isInstantiated() ? this.milliseconds : -1; |
| } |
| |
| /** |
| * @return String representation of object. See class comments. |
| */ |
| public String toString() { |
| ensureFull(); |
| if (!this.knowsFull) { |
| return unknownTime; |
| } |
| StringBuffer buf = new StringBuffer(); |
| boolean started = false; |
| if (this.years > 0) { |
| buf.append(this.years); |
| buf.append(" "); |
| buf.append(yearsString); |
| started = true; |
| } |
| if (started || this.days > 0) { |
| if (started) { |
| buf.append(" "); |
| } |
| buf.append(this.days); |
| buf.append(" "); |
| buf.append(daysString); |
| started = true; |
| } |
| if (started || this.hours > 0) { |
| if (started) { |
| buf.append(" "); |
| } |
| buf.append(this.hours); |
| buf.append(" "); |
| buf.append(hoursString); |
| started = true; |
| } |
| if (started || this.minutes > 0) { |
| if (started) { |
| buf.append(" "); |
| } |
| buf.append(this.minutes); |
| buf.append(" "); |
| buf.append(minutesString); |
| started = true; |
| } |
| if (started || this.seconds > 0) { |
| if (started) { |
| buf.append(" "); |
| } |
| buf.append(this.seconds); |
| started = true; |
| } |
| if (started) { |
| buf.append("."); |
| if (this.milliseconds < 100) { |
| buf.append("0"); |
| if (this.milliseconds < 10) { |
| buf.append("0"); |
| } |
| } |
| buf.append(this.milliseconds); |
| buf.append(" "); |
| buf.append(secondsString); |
| } else { |
| buf.append(this.milliseconds); |
| buf.append(" "); |
| buf.append(msString); |
| } |
| return buf.toString(); |
| } |
| |
| private void ensureAll() { |
| if (this.knowsMS || !this.knowsFull) { |
| return; |
| } |
| this.all = 0; |
| this.all += this.years * msYear; |
| this.all += this.days * msDay; |
| this.all += this.hours * msHour; |
| this.all += this.minutes * msMinute; |
| this.all += this.seconds * msSecond; |
| this.all += this.milliseconds; |
| this.knowsMS = true; |
| } |
| |
| private void ensureFull() { |
| if (this.knowsFull || !this.knowsMS) { |
| return; |
| } |
| long t = this.all; |
| this.years = (int) (t / msYear); |
| t %= msYear; |
| this.days = (int) (t / msDay); |
| t %= msDay; |
| this.hours = (int) (t / msHour); |
| t %= msHour; |
| this.minutes = (int) (t / msMinute); |
| t %= msMinute; |
| this.seconds = (int) (t / msSecond); |
| t %= msSecond; |
| this.milliseconds = (int) t; |
| this.knowsFull = true; |
| } |
| |
| } |