org.conqat.lib.commons.date.DurationUtils Maven / Gradle / Ivy
Show all versions of teamscale-lib-commons Show documentation
/*
* Copyright (c) CQSE GmbH
*
* Licensed 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.conqat.lib.commons.date;
import java.time.Duration;
import java.time.Instant;
import java.time.Period;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit;
/**
* Helper methods to deal with durations in a more readable fashion.
*/
@SuppressWarnings({ "WeakerAccess", "unused" })
public class DurationUtils {
/** The number of nanoseconds per microsecond. */
public static final int NANOS_PER_MICRO = 1000;
/** The number of microseconds per millisecond. */
public static final int MICROS_PER_MILLI = 1000;
/** The number of nanoseconds per millisecond. */
public static final int NANOS_PER_MILLI = NANOS_PER_MICRO * MICROS_PER_MILLI;
/** The number of milliseconds per second. */
public static final int MILLIS_PER_SECOND = 1000;
/** The number of microseconds per second. */
public static final int MICROS_PER_SECOND = MICROS_PER_MILLI * MILLIS_PER_SECOND;
/** The number of nanoseconds per second. */
public static final int NANOS_PER_SECOND = NANOS_PER_MILLI * MILLIS_PER_SECOND;
/** The number of seconds per minute. */
public static final int SECONDS_PER_MINUTE = 60;
/** The number of milliseconds per minute. */
public static final int MILLIS_PER_MINUTE = MILLIS_PER_SECOND * SECONDS_PER_MINUTE;
/** The number of microseconds per minute. */
public static final int MICROS_PER_MINUTE = MICROS_PER_SECOND * SECONDS_PER_MINUTE;
/** The number of nanoseconds per minute. */
public static final long NANOS_PER_MINUTE = NANOS_PER_SECOND * (long) SECONDS_PER_MINUTE;
/** The number of minutes per hour. */
public static final int MINUTES_PER_HOUR = 60;
/** The number of seconds per hour. */
public static final int SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
/** The number of milliseconds per hour. */
public static final int MILLIS_PER_HOUR = MILLIS_PER_MINUTE * MINUTES_PER_HOUR;
/** The number of microseconds per hour. */
public static final long MICROS_PER_HOUR = MICROS_PER_MINUTE * (long) MINUTES_PER_HOUR;
/** The number of nanoseconds per hour. */
public static final long NANOS_PER_HOUR = NANOS_PER_MINUTE * MINUTES_PER_HOUR;
/** The number of hours per day (no daylight saving time). */
public static final int HOURS_PER_DAY = 24;
/** The number of minutes per day (no daylight saving time). */
public static final int MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY;
/** The number of seconds per day (no daylight saving time). */
public static final int SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY;
/** The number of milliseconds per day (no daylight saving time). */
public static final int MILLIS_PER_DAY = MILLIS_PER_HOUR * HOURS_PER_DAY;
/** The number of microseconds per day (no daylight saving time). */
public static final long MICROS_PER_DAY = MICROS_PER_HOUR * HOURS_PER_DAY;
/** The number of nanoseconds per day (no daylight saving time). */
public static final long NANOS_PER_DAY = NANOS_PER_HOUR * HOURS_PER_DAY;
/** The number of days per year (non leap year). */
public static final int DAYS_PER_YEAR = 365;
/** The number of hours per year (non leap year, no daylight saving time). */
public static final int HOURS_PER_YEAR = HOURS_PER_DAY * DAYS_PER_YEAR;
/** The number of minutes per year (non leap year, no daylight saving time). */
public static final int MINUTES_PER_YEAR = MINUTES_PER_DAY * DAYS_PER_YEAR;
/** The number of seconds per year (non leap year, no daylight saving time). */
public static final int SECONDS_PER_YEAR = SECONDS_PER_DAY * DAYS_PER_YEAR;
/**
* The number of milliseconds per year (non leap year, no daylight saving time).
*/
public static final long MILLIS_PER_YEAR = MILLIS_PER_DAY * (long) DAYS_PER_YEAR;
/**
* The number of microseconds per year (non leap year, no daylight saving time).
*/
public static final long MICROS_PER_YEAR = MICROS_PER_DAY * DAYS_PER_YEAR;
/**
* The number of nanoseconds per year (non leap year, no daylight saving time).
*/
public static final long NANOS_PER_YEAR = NANOS_PER_DAY * DAYS_PER_YEAR;
/** {@link Duration} of one millisecond. */
public static final Duration ONE_MILLISECOND = Duration.ofMillis(1);
/** {@link Duration} of one second. */
public static final Duration ONE_SECOND = Duration.ofSeconds(1);
/** {@link Duration} of one minute. */
public static final Duration ONE_MINUTE = Duration.ofMinutes(1);
/** {@link Duration} of one hour. */
public static final Duration ONE_HOUR = Duration.ofHours(1);
// There is explicitly no constant for ONE_DAY here!
// The reason is that there are two different ways to see one day:
// Either as 24 hours (as Duration does it) or as one calendar day (as Period
// does it), which sometimes may be shorter/longer than 24 hours for days with
// daylights saving time change.
// The correct representation is dependent on the use-case, and in order to
// avoid a potential misuse, no constant for it is declared.
/** {@link Period} of one week (i.e. 7 days). */
public static final Period ONE_WEEK = Period.ofDays(7);
/** {@link Period} of one month (no fixed day amount). */
public static final Period ONE_MONTH = Period.ofMonths(1);
/** {@link Period} of one year (no fixed day amount). */
public static final Period ONE_YEAR = Period.ofYears(1);
/**
* Check if the given duration has elapsed since the given point in time.
*
* @param duration
* The duration.
* @param sinceMillisTimestampUTC
* The timestamp of the event after that the given duration should have passed.
*/
public static boolean elapsed(Duration duration, long sinceMillisTimestampUTC) {
long currentMillis = DateTimeUtils.getClock().millis();
long elapsedSince = currentMillis - sinceMillisTimestampUTC;
long requiredToElapse = duration.toMillis();
return elapsedSince > requiredToElapse;
}
/**
* Check if the given duration has elapsed since the given point in time.
*
* @param duration
* The duration.
* @param since
* Instant of the event after that the given duration should have passed.
*/
public static boolean elapsed(Duration duration, Instant since) {
Duration elapsedSince = Duration.between(since, Instant.now());
return !elapsedSince.minus(duration).isNegative();
}
/** Formats a duration in a human-readable way (e.g. 1h 20min 5s 123ms). */
public static String formatDurationHumanReadable(Duration duration) {
long milliseconds = duration.toMillis() % MILLIS_PER_SECOND;
long seconds = (duration.toMillis() / MILLIS_PER_SECOND) % SECONDS_PER_MINUTE;
long minutes = (duration.toMillis() / MILLIS_PER_MINUTE) % MINUTES_PER_HOUR;
long hours = (duration.toMillis() / MILLIS_PER_HOUR);
StringBuilder builder = new StringBuilder();
if (hours > 0) {
builder.append(hours).append("h ");
}
if (hours > 0 || minutes > 0) {
builder.append(minutes).append("min ");
}
if (hours > 0 || minutes > 0 || seconds > 0) {
builder.append(seconds).append("s ");
}
builder.append(milliseconds).append("ms");
return builder.toString();
}
/**
* Converts the provided {@link TemporalAmount} into a {@link Duration}.
*
* Please note, that this calculation is not always accurate. For example the exact amount of
* milliseconds in one {@link java.time.temporal.ChronoUnit#YEARS year}, depends on the actual year
* (keyword: leap year).
*
* @see Duration
* @see java.time.Period Period
* @see TemporalUnit#getDuration()
*/
public static Duration toDuration(TemporalAmount temporalAmount) {
if (temporalAmount instanceof Duration) {
return (Duration) temporalAmount;
}
Duration result = Duration.ZERO;
for (TemporalUnit unit : temporalAmount.getUnits()) {
Duration baseDuration = unit.getDuration();
long amount = temporalAmount.get(unit);
result = result.plus(baseDuration.multipliedBy(amount));
}
return result;
}
/**
* Compares two duration objects and returns the smaller one.
*/
public static Duration getSmallerDuration(Duration duration1, Duration duration2) {
return duration1.compareTo(duration2) <= 0 ? duration1 : duration2;
}
}