Add DurationUtils.

This commit is contained in:
Gary Gregory 2021-02-11 16:47:38 -05:00
parent fa880a43ed
commit ff6c5f65a5
4 changed files with 141 additions and 0 deletions

View File

@ -88,6 +88,8 @@ The <action> type attribute can be add,update,fix,remove.
<action type="add" dev="ggregory" due-to="Gary Gregory">Add JavaVersion.JAVA_17.</action>
<action issue="LANG-1636" type="add" dev="ggregory" due-to="">Add missing boolean[] join method #686.</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add StringUtils.substringBefore(String, int).</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add Range.INTEGER.</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add DurationUtils.</action>
<action type="add" dev="jochen">Introduce the use of @Nonnull, and @Nullable, and the Objects class as a helper tool.</action>
<!-- UPDATE -->
<action type="update" dev="ggregory" due-to="Gary Gregory">Enable Dependabot #587.</action>

View File

@ -70,6 +70,20 @@ public class NumberUtils {
/** Reusable Float constant for minus one. */
public static final Float FLOAT_MINUS_ONE = Float.valueOf(-1.0f);
/**
* {@link Integer#MAX_VALUE} as a {@link Long}.
*
* @since 3.12.0
*/
public static final Long LONG_INT_MAX_VALUE = Long.valueOf(Integer.MAX_VALUE);
/**
* {@link Integer#MIN_VALUE} as a {@link Long}.
*
* @since 3.12.0
*/
public static final Long LONG_INT_MIN_VALUE = Long.valueOf(Integer.MIN_VALUE);
/**
* <p>{@code NumberUtils} instances should NOT be constructed in standard programming.

View File

@ -0,0 +1,60 @@
/*
* 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.commons.lang3.time;
import java.time.Duration;
import java.util.Objects;
import org.apache.commons.lang3.Range;
import org.apache.commons.lang3.math.NumberUtils;
/**
* Utilities for {@link Duration}.
*
* @since 3.12.0
*/
public class DurationUtils {
/**
* An Integer Range that accepts Longs.
*/
static final Range<Long> LONG_TO_INT_RANGE = Range.between(
NumberUtils.LONG_INT_MIN_VALUE,
NumberUtils.LONG_INT_MAX_VALUE);
/**
* Converts a Duration to milliseconds bound to an int (instead of a long).
* <p>
* Handy for low-level APIs that take millisecond timeouts in ints rather than longs.
* </p>
* <ul>
* <li>If the duration milliseconds are greater than {@link Integer#MAX_VALUE}, then return
* {@link Integer#MAX_VALUE}.</li>
* <li>If the duration milliseconds are lesser than {@link Integer#MIN_VALUE}, then return
* {@link Integer#MIN_VALUE}.</li>
* </ul>
*
* @param duration The duration to convert, not null.
* @return int milliseconds.
*/
public static int toMillisInt(final Duration duration) {
Objects.requireNonNull(duration, "duration");
// intValue() does not do a narrowing conversion here
return DurationUtils.LONG_TO_INT_RANGE.fit(Long.valueOf(duration.toMillis())).intValue();
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.commons.lang3.time;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.Duration;
import org.apache.commons.lang3.math.NumberUtils;
import org.junit.jupiter.api.Test;
/**
* Tests {@link DurationUtils}.
*/
public class DurationUtilsTest {
@Test
public void testLongToIntRangeFit() {
assertEquals(0, DurationUtils.LONG_TO_INT_RANGE.fit(0L));
//
assertEquals(Integer.MIN_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MIN_VALUE));
assertEquals(Integer.MIN_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MIN_VALUE - 1));
assertEquals(Integer.MIN_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MIN_VALUE - 2));
assertEquals(Integer.MAX_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MAX_VALUE));
assertEquals(Integer.MAX_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MAX_VALUE + 1));
assertEquals(Integer.MAX_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(NumberUtils.LONG_INT_MAX_VALUE + 2));
//
assertEquals(Integer.MIN_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(Long.MIN_VALUE));
assertEquals(Integer.MAX_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit(Long.MAX_VALUE));
//
assertEquals(Short.MIN_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit((long) Short.MIN_VALUE));
assertEquals(Short.MAX_VALUE, DurationUtils.LONG_TO_INT_RANGE.fit((long) Short.MAX_VALUE));
}
@Test
public void testToMillisInt() {
assertEquals(0, DurationUtils.toMillisInt(Duration.ZERO));
assertEquals(1, DurationUtils.toMillisInt(Duration.ofMillis(1)));
//
assertEquals(Integer.MIN_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(Integer.MIN_VALUE)));
assertEquals(Integer.MAX_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(Integer.MAX_VALUE)));
assertEquals(Integer.MAX_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(NumberUtils.LONG_INT_MAX_VALUE + 1)));
assertEquals(Integer.MAX_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(NumberUtils.LONG_INT_MAX_VALUE + 2)));
assertEquals(Integer.MIN_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(NumberUtils.LONG_INT_MIN_VALUE - 1)));
assertEquals(Integer.MIN_VALUE, DurationUtils.toMillisInt(Duration.ofMillis(NumberUtils.LONG_INT_MIN_VALUE - 2)));
//
assertEquals(Integer.MIN_VALUE, DurationUtils.toMillisInt(Duration.ofNanos(Long.MIN_VALUE)));
assertEquals(Integer.MAX_VALUE, DurationUtils.toMillisInt(Duration.ofNanos(Long.MAX_VALUE)));
}
}