Skip to content

Commit

Permalink
Add durations.
Browse files Browse the repository at this point in the history
Add periods.
Subtract durations.
Subtract periods.
Multiply durations by doubles.
Multiply periods by longs.
Divide durations.
  • Loading branch information
chipkent committed May 22, 2024
1 parent 98bb980 commit 655f4d0
Show file tree
Hide file tree
Showing 2 changed files with 331 additions and 6 deletions.
186 changes: 180 additions & 6 deletions engine/time/src/main/java/io/deephaven/time/DateTimeUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static io.deephaven.util.QueryConstants.NULL_INT;
import static io.deephaven.util.QueryConstants.NULL_LONG;
import static io.deephaven.util.QueryConstants.*;
import static java.time.format.DateTimeFormatter.*;

/**
Expand Down Expand Up @@ -1652,6 +1651,44 @@ public static ZonedDateTime plus(@Nullable final ZonedDateTime dateTime, @Nullab
}
}

/**
* Adds two durations.
*
* @param duration1 first duration
* @param duration2 second duration
* @return {@code null} if either input is {@code null}; otherwise the sum of the two durations
*/
public static Duration plus(@Nullable final Duration duration1, @Nullable final Duration duration2) {
if (duration1 == null || duration2 == null) {
return null;
}

try {
return duration1.plus(duration2);
} catch (Exception ex) {
throw new DateTimeOverflowException(ex);
}
}

/**
* Adds two periods.
*
* @param period1 first period
* @param period2 second period
* @return {@code null} if either input is {@code null}; otherwise the sum of the two periods
*/
public static Period plus(@Nullable final Period period1, @Nullable final Period period2) {
if (period1 == null || period2 == null) {
return null;
}

try {
return period1.plus(period2);
} catch (Exception ex) {
throw new DateTimeOverflowException(ex);
}
}

/**
* Subtracts days from a {@link LocalDate}.
*
Expand Down Expand Up @@ -1871,6 +1908,44 @@ public static long minus(@Nullable final ZonedDateTime dateTime1, @Nullable fina
return checkUnderflowMinus(epochNanos(dateTime1), epochNanos(dateTime2), true);
}

/**
* Subtracts two durations.
*
* @param duration1 first duration
* @param duration2 second duration
* @return {@code null} if either input is {@code null}; otherwise the difference of the two durations
*/
public static Duration minus(@Nullable final Duration duration1, @Nullable final Duration duration2) {
if (duration1 == null || duration2 == null) {
return null;
}

try {
return duration1.minus(duration2);
} catch (Exception ex) {
throw new DateTimeOverflowException(ex);
}
}

/**
* Subtracts two periods.
*
* @param period1 first period
* @param period2 second period
* @return {@code null} if either input is {@code null}; otherwise the difference of the two periods
*/
public static Period minus(@Nullable final Period period1, @Nullable final Period period2) {
if (period1 == null || period2 == null) {
return null;
}

try {
return period1.minus(period2);
} catch (Exception ex) {
throw new DateTimeOverflowException(ex);
}
}

/**
* Multiply a duration by a scalar.
*
Expand All @@ -1894,11 +1969,43 @@ public static Duration multiply(final Duration duration, final long scalar) {
* @return {@code null} if either input is {@code null}; otherwise the duration multiplied by the scalar
*/
public static Duration multiply(final long scalar, final Duration duration) {
if (duration == null || scalar == NULL_LONG) {
return multiply(duration, scalar);
}

/**
* Multiply a duration by a scalar.
*
* @param duration the duration to multiply
* @param scalar the scalar to multiply by
* @return {@code null} if either input is {@code null}; otherwise the duration multiplied by the scalar
*/
public static Duration multiply(final Duration duration, final double scalar) {
if (duration == null || scalar == NULL_DOUBLE) {
return null;
}

return duration.multipliedBy(scalar);
if(Double.isNaN(scalar)) {
throw new DateTimeOverflowException("Scalar value is NaN");
}

final double product = duration.toNanos() * scalar;

if(product > Long.MAX_VALUE || product < Long.MIN_VALUE) {
throw new DateTimeOverflowException("Product value is too large to be cast to a long");
}

return Duration.ofNanos((long) product);
}

/**
* Multiply a duration by a scalar.
*
* @param duration the duration to multiply
* @param scalar the scalar to multiply by
* @return {@code null} if either input is {@code null}; otherwise the duration multiplied by the scalar
*/
public static Duration multiply(final double scalar, final Duration duration) {
return multiply(duration, scalar);
}

/**
Expand All @@ -1924,13 +2031,80 @@ public static Period multiply(final Period period, final int scalar) {
* @return {@code null} if either input is {@code null}; otherwise the period multiplied by the scalar
*/
public static Period multiply(final int scalar, final Period period) {
if (period == null || scalar == NULL_INT) {
return multiply(period, scalar);
}

/**
* Multiply a period by a scalar.
*
* @param period the period to multiply
* @param scalar the scalar to multiply by
* @return {@code null} if either input is {@code null}; otherwise the period multiplied by the scalar
*/
public static Period multiply(final Period period, final long scalar) {
if (period == null || scalar == NULL_LONG) {
return null;
}

return period.multipliedBy(scalar);
if(scalar > Integer.MAX_VALUE || scalar < Integer.MIN_VALUE) {
throw new DateTimeOverflowException("Scalar value is too large to be cast to an int");
}

return period.multipliedBy((int) scalar);
}

/**
* Multiply a period by a scalar.
*
* @param period the period to multiply
* @param scalar the scalar to multiply by
* @return {@code null} if either input is {@code null}; otherwise the period multiplied by the scalar
*/
public static Period multiply(final long scalar, final Period period) {
return multiply(period, scalar);
}

/**
* Divide a duration by a scalar.
*
* @param duration the duration to divide
* @param scalar the scalar to divide by
* @return {@code null} if either input is {@code null}; otherwise the duration divide by the scalar
*/
public static Duration divide(final Duration duration, final long scalar) {
if (duration == null || scalar == NULL_LONG) {
return null;
}

if(scalar == 0) {
throw new DateTimeOverflowException("Scalar value is zero");
}

return duration.dividedBy(scalar);
}

/**
* Divide a duration by a scalar.
*
* @param duration the duration to divide
* @param scalar the scalar to divide by
* @return {@code null} if either input is {@code null}; otherwise the duration divide by the scalar
*/
public static Duration divide(final Duration duration, final double scalar) {
if (duration == null || scalar == NULL_DOUBLE) {
return null;
}

if(Double.isNaN(scalar)) {
throw new DateTimeOverflowException("Scalar value is NaN");
}

if(scalar == 0) {
throw new DateTimeOverflowException("Scalar value is zero");
}

return Duration.ofNanos((long) (duration.toNanos() / scalar));
}

/**
* Returns the difference in nanoseconds between two instant values.
Expand Down
Loading

0 comments on commit 655f4d0

Please sign in to comment.