/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.common.time;
import java.util.concurrent.TimeUnit;
/**
* Represents a duration of time
*/
public class TimeSpan {
/**
* @param nanos Duration, in nanoseconds
* @return The time span representing the given duration
*/
public static TimeSpan fromNanos(long nanos) {
return new TimeSpan(nanos, TimeUnit.NANOSECONDS);
}
/**
* @param micros Duration, in microseconds
* @return The time span representing the given duration
*/
public static TimeSpan fromMicros(long micros) {
return new TimeSpan(micros, TimeUnit.MICROSECONDS);
}
/**
* @param millis Duration, in milliseconds
* @return The time span representing the given duration
*/
public static TimeSpan fromMillis(long millis) {
return new TimeSpan(millis, TimeUnit.MILLISECONDS);
}
/**
* @param seconds Duration, in seconds
* @return The time span representing the given duration
*/
public static TimeSpan fromSeconds(long seconds) {
return new TimeSpan(seconds, TimeUnit.SECONDS);
}
/**
* @param minutes Duration, in minutes
* @return The time span representing the given duration
*/
public static TimeSpan fromMinutes(long minutes) {
return new TimeSpan(minutes, TimeUnit.MINUTES);
}
/**
* @param hours Duration, in hours
* @return The time span representing the given duration
*/
public static TimeSpan fromHours(long hours) {
return new TimeSpan(hours, TimeUnit.HOURS);
}
/**
* @param days Duration, in days
* @return The time span representing the given duration
*/
public static TimeSpan fromDays(long days) {
return new TimeSpan(days, TimeUnit.DAYS);
}
/**
* Actual time span, normalized to nanoseconds (shortest time supported by
* {@link java.util.concurrent.TimeUnit})
*/
private final long mDurationNanos;
/**
* Constructs an object representing the given time span
* @param duration Duration, in the given units
* @param timeUnit Unit duration is given
*/
public TimeSpan(long duration, TimeUnit timeUnit) {
mDurationNanos = timeUnit.toNanos(duration);
}
/**
* @return Duration in nanoseconds
*/
public long toNanos() {
return mDurationNanos;
}
/**
* @return Duration in microseconds
*/
public long toMicros() {
return TimeUnit.NANOSECONDS.toMicros(mDurationNanos);
}
/**
* @return Duration in milliseconds
*/
public long toMillis() {
return TimeUnit.NANOSECONDS.toMillis(mDurationNanos);
}
/**
* @return Duration in seconds
*/
public long toSeconds() {
return TimeUnit.NANOSECONDS.toSeconds(mDurationNanos);
}
/**
* @return Duration in minutes
*/
public long toMinutes() {
return TimeUnit.NANOSECONDS.toMinutes(mDurationNanos);
}
/**
* @return Duration in hours
*/
public long toHours() {
return TimeUnit.NANOSECONDS.toHours(mDurationNanos);
}
/**
* @return Duration in days
*/
public long toDays() {
return TimeUnit.NANOSECONDS.toDays(mDurationNanos);
}
/**
* Get duration as the given time unit
*
* @param timeUnit Time unit to get the duration in
* @return Duration in requested time unit
*/
public long as(TimeUnit timeUnit) {
return timeUnit.convert(mDurationNanos, TimeUnit.NANOSECONDS);
}
@Override
public String toString() {
long days = toDays();
long hours = toHours() % 24;
long minutes = toMinutes() % 60;
long seconds = toSeconds() % 60;
long millis = toMillis() % 1000;
long micros = toMicros() % 1000;
long nanos = toNanos() % 1000;
String sep = "";
StringBuilder sb = new StringBuilder("TimeSpan{");
if (days > 0) {
sb.append(days).append(" ");
pluralize(sb, "Day", days);
sep = ", ";
}
if (hours > 0) {
sb.append(sep).append(hours).append(" ");
pluralize(sb, "Hour", hours);
sep = ", ";
}
if (minutes > 0) {
sb.append(sep).append(minutes).append(" ");
pluralize(sb, "Minute", minutes);
sep = ", ";
}
if (seconds > 0) {
sb.append(sep).append(seconds).append(" ");
pluralize(sb, "Second", seconds);
sep = ", ";
}
if (millis > 0) {
sb.append(sep).append(millis).append(" ");
pluralize(sb, "Milli", millis);
sep = ", ";
}
if (micros > 0) {
sb.append(sep).append(micros).append(" ");
pluralize(sb, "Micro", micros);
sep = ", ";
}
if (nanos > 0) {
sb.append(sep).append(nanos).append(" ");
pluralize(sb, "Nano", nanos);
}
sb.append("}");
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TimeSpan timeSpan = (TimeSpan) o;
if (mDurationNanos != timeSpan.mDurationNanos) return false;
return true;
}
@Override
public int hashCode() {
return (int)(mDurationNanos ^ (mDurationNanos >>> 32));
}
private static final void pluralize(StringBuilder sb, String singular, long num) {
sb.append(singular);
if (num > 1) {
sb.append("s");
}
}
}