org.apache.wicket.util.time.Duration Maven / Gradle / Ivy
Show all versions of org.ops4j.pax.wicket.service Show documentation
/*
* 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.wicket.util.time;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.wicket.util.string.StringValue;
import org.apache.wicket.util.string.StringValueConversionException;
import org.apache.wicket.util.thread.ICode;
import org.slf4j.Logger;
/**
* A Duration
is an immutable length of time stored as a number of milliseconds.
* Various factory and conversion methods are available for convenience.
*
* These static factory methods allow easy construction of value objects using either long values
* like seconds(2034)
or hours(3)
:
*
*
* Duration.milliseconds(long)
* Duration.seconds(int)
* Duration.minutes(int)
* Duration.hours(int)
* Duration.days(int)
*
*
* ...or double-precision floating point values like days(3.2)
:
*
*
* Duration.milliseconds(double)
* Duration.seconds(double)
* Duration.minutes(double)
* Duration.hours(double)
* Duration.days(double)
*
*
* In the case of milliseconds(double)
, the value will be rounded off to the nearest
* integral millisecond using Math.round()
.
*
* The precise number of milliseconds represented by a Duration
object can be retrieved
* by calling the getMilliseconds
method. The value of a Duration
object
* in a given unit like days or hours can be retrieved by calling one of the following unit methods,
* each of which returns a double-precision floating point number:
*
*
* seconds()
* minutes()
* hours()
* days()
*
*
* Values can be added and subtracted using the add(Duration)
and
* subtract(Duration)
methods, each of which returns a new immutable
* Duration
object.
*
* String
values can be converted to Duration
objects using the static
* valueOf
factory methods. The String
format is the opposite of the one
* created by toString()
, which converts a Duration
object to a readable
* form, such as "3.2 hours" or "32.5 minutes". Valid units are: milliseconds, seconds, minutes
* hours and days. Correct English plural forms are used in creating String
values and
* are parsed as well. The Locale
is respected and "," will be used instead of "." in
* the Eurozone.
*
* The benchmark method will "benchmark" a Runnable
or an {@link ICode} implementing
* object, returning a Duration
object that represents the amount of time elapsed in
* running the code.
*
* Finally, the sleep
method will sleep for the value of a Duration
.
*
* @author Jonathan Locke
* @since 1.2.6
*/
public class Duration extends AbstractTimeValue
{
private static final long serialVersionUID = 1L;
/** Constant for maximum duration. */
public static final Duration MAXIMUM = milliseconds(Long.MAX_VALUE);
/** Constant for no duration. */
public static final Duration NONE = milliseconds(0);
/** Constant for one day. */
public static final Duration ONE_DAY = days(1);
/** Constant for one hour. */
public static final Duration ONE_HOUR = hours(1);
/** Constant for on minute. */
public static final Duration ONE_MINUTE = minutes(1);
/** Constant for one second. */
public static final Duration ONE_SECOND = seconds(1);
/** Constant for one week. */
public static final Duration ONE_WEEK = days(7);
/** pattern to match strings */
private static final Pattern pattern = Pattern.compile(
"([0-9]+([.,][0-9]+)?)\\s+(millisecond|second|minute|hour|day)s?", Pattern.CASE_INSENSITIVE);
/**
* Benchmark the given command.
*
* @param code
* an ICode
* @param log
* optional logger to use with errors and exceptions
* @return the Time
value it took to run the code
*/
public static Duration benchmark(final ICode code, final Logger log)
{
// Get time before running code
final Time start = Time.now();
// Run the code
code.run(log);
// Return the difference
return Time.now().subtract(start);
}
/**
* Benchmark the given command.
*
* @param code
* a Runnable
* @return the Time
value it took to run the code
*/
public static Duration benchmark(final Runnable code)
{
// Get time before running code
final Time start = Time.now();
// Run code
code.run();
// Return the difference
return Time.now().subtract(start);
}
/**
* Retrieves the Duration
based on days.
*
* @param days
* days double
value
* @return the Duration
based on days
*/
public static Duration days(final double days)
{
return hours(24.0 * days);
}
/**
* Retrieves the Duration
based on days.
*
* @param days
* days int
value
* @return the Duration
based on days
*/
public static Duration days(final int days)
{
return hours(24 * days);
}
/**
* Calculates the amount of time elapsed since start time.
*
* @param start
* the start Time
* @return the elapsed period as a Duration
* @throws IllegalStateException
* if start Time
is in the future
*/
public static Duration elapsed(final Time start)
{
return start.elapsedSince();
}
/**
* Retrieves the Duration
based on hours.
*
* @param hours
* hours double
value
* @return the Duration
based on hours
*/
public static Duration hours(final double hours)
{
return minutes(60.0 * hours);
}
/**
* Retrieves the Duration
based on hours.
*
* @param hours
* hours int
value
* @return the Duration
based on hours
*/
public static Duration hours(final int hours)
{
return minutes(60 * hours);
}
/**
* Retrieves the Duration
based on milliseconds.
*
* @param milliseconds
* milliseconds double
value
* @return the Duration
based on milliseconds
*/
public static Duration milliseconds(final double milliseconds)
{
return milliseconds(Math.round(milliseconds));
}
/**
* Retrieves the Duration
based on milliseconds.
*
* @param milliseconds
* milliseconds long
value
* @return the Duration
based on milliseconds
*/
public static Duration milliseconds(final long milliseconds)
{
return new Duration(milliseconds);
}
/**
* Retrieves the Duration
based on minutes.
*
* @param minutes
* minutes double
value
* @return the Duration
based on minutes
*/
public static Duration minutes(final double minutes)
{
return seconds(60.0 * minutes);
}
/**
* Retrieves the Duration
based on minutes.
*
* @param minutes
* minutes int
value
* @return the Duration
based on minutes
*/
public static Duration minutes(final int minutes)
{
return seconds(60 * minutes);
}
/**
* Retrieves the Duration
based on seconds.
*
* @param seconds
* seconds double
value
* @return the Duration
based on seconds
*/
public static Duration seconds(final double seconds)
{
return milliseconds(seconds * 1000.0);
}
/**
* Retrieves the Duration
based on seconds.
*
* @param seconds
* seconds int
value
* @return the Duration
based on seconds
*/
public static Duration seconds(final int seconds)
{
return milliseconds(seconds * 1000L);
}
/**
* Retrieves the given long
as a Duration
.
*
* @param time
* the duration long
value in milliseconds
* @return the Duration
value
*/
public static Duration valueOf(final long time)
{
return new Duration(time);
}
/**
* Converts the given String
to a new Duration
object. The string can
* take the form of a floating point number followed by a number of milliseconds, seconds,
* minutes, hours or days. For example "6 hours" or "3.4 days". Parsing is case-insensitive.
*
* @param string
* a String
to parse
* @return the Duration
value of the given String
* @throws StringValueConversionException
*/
public static Duration valueOf(final String string) throws StringValueConversionException
{
return valueOf(string, Locale.getDefault());
}
/**
* Converts the given String
to a new Duration
object. The string can
* take the form of a floating point number followed by a number of milliseconds, seconds,
* minutes, hours or days. For example "6 hours" or "3.4 days". Parsing is case-insensitive.
*
* @param string
* a String
to parse
* @param locale
* the Locale
used for parsing
* @return the Duration
value of the given String
* @throws StringValueConversionException
*/
public static Duration valueOf(final String string, final Locale locale)
throws StringValueConversionException
{
final Matcher matcher = pattern.matcher(string);
if (matcher.matches())
{
final double value = StringValue.valueOf(matcher.group(1), locale).toDouble();
final String units = matcher.group(3);
if (units.equalsIgnoreCase("millisecond"))
{
return milliseconds(value);
}
else if (units.equalsIgnoreCase("second"))
{
return seconds(value);
}
else if (units.equalsIgnoreCase("minute"))
{
return minutes(value);
}
else if (units.equalsIgnoreCase("hour"))
{
return hours(value);
}
else if (units.equalsIgnoreCase("day"))
{
return days(value);
}
else
{
throw new StringValueConversionException("Unrecognized units: " + string);
}
}
else
{
throw new StringValueConversionException("Unable to parse duration: " + string);
}
}
/**
* Private constructor forces use of static factory methods.
*
* @param milliseconds
* number of milliseconds in this Duration
*/
protected Duration(final long milliseconds)
{
super(milliseconds);
}
/**
* Adds a given Duration
to this Duration
.
*
* @param duration
* the Duration
to add
* @return the sum of the Duration
s
*/
public Duration add(final Duration duration)
{
return valueOf(getMilliseconds() + duration.getMilliseconds());
}
/**
* Retrieves the number of days of the current Duration
.
*
* @return number of days of the current Duration
*/
public final double days()
{
return hours() / 24.0;
}
/**
* Retrieves the number of hours of the current Duration
.
*
* @return number of hours of the current Duration
*/
public final double hours()
{
return minutes() / 60.0;
}
/**
* Retrieves the number of minutes of the current Duration
.
*
* @return number of minutes of the current Duration
*/
public final double minutes()
{
return seconds() / 60.0;
}
/**
* Retrieves the number of seconds of the current Duration
.
*
* @return number of seconds of the current Duration
*/
public final double seconds()
{
return getMilliseconds() / 1000.0;
}
/**
* Sleeps for the current Duration
.
*/
public final void sleep()
{
if (getMilliseconds() > 0)
{
try
{
Thread.sleep(getMilliseconds());
}
catch (InterruptedException e)
{
// Ignored
}
}
}
/**
* Subtracts a given Duration
from this Duration
.
*
* @param that
* the Duration
to subtract
* @return this Duration
minus that Duration
*/
public Duration subtract(final Duration that)
{
return valueOf(getMilliseconds() - that.getMilliseconds());
}
/**
* Wait for this duration on the given monitor
*
* @param object
* The monitor to wait on
*/
public void wait(Object object)
{
try
{
object.wait(getMilliseconds());
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
/**
* Retrieves the String
representation of this Duration
in days,
* hours, minutes, seconds or milliseconds, as appropriate. Uses the default Locale
* .
*
* @return a String
representation
*/
@Override
public String toString()
{
return toString(Locale.getDefault());
}
/**
* Retrieves the String
representation of this Duration
in days,
* hours, minutes, seconds or milliseconds, as appropriate.
*
* @param locale
* a Locale
* @return a String
representation
*/
public String toString(final Locale locale)
{
if (getMilliseconds() >= 0)
{
if (days() >= 1.0)
{
return unitString(days(), "day", locale);
}
if (hours() >= 1.0)
{
return unitString(hours(), "hour", locale);
}
if (minutes() >= 1.0)
{
return unitString(minutes(), "minute", locale);
}
if (seconds() >= 1.0)
{
return unitString(seconds(), "second", locale);
}
return getMilliseconds() + " milliseconds";
}
else
{
return "N/A";
}
}
/**
* Converts a value to a unit-suffixed value, taking care of English singular/plural suffix.
*
* @param value
* a double
value to format
* @param units
* the units to apply singular or plural suffix to
* @param locale
* the Locale
* @return a String
representation
*/
private String unitString(final double value, final String units, final Locale locale)
{
return StringValue.valueOf(value, locale) + " " + units + ((value > 1.0) ? "s" : "");
}
}