Skip to content

Duration methods #416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
use flake
layout node
eval "$shellHook"
4 changes: 2 additions & 2 deletions .github/workflows/scala.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- name: Set up JDK 8
uses: olafurpg/setup-scala@v13
with:
java-version: 1.8
java-version: 1.9
- name: Cache scala dependencies
uses: coursier/cache-action@v6
# - name: Checking your code format
Expand All @@ -37,7 +37,7 @@ jobs:
- name: Setup Scala and Java
uses: olafurpg/setup-scala@v13
with:
java-version: 1.8
java-version: 1.9
- name: Cache scala dependencies
uses: coursier/cache-action@v6
- name: Run tests
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ tzdb/js/src/main/resources/
.bloop/
.metals/
project/metals.sbt
.direnv/
.bsp/
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ object IsoFields {
if (resolverStyle eq ResolverStyle.LENIENT) {
val qoy: Long = qoyLong
date = LocalDate.of(y, 1, 1)
date = date.plusMonths(Math.multiplyExact(Math.subtractExact(qoy, 1), 3))
date = date.plusMonths(Math.multiplyExact(Math.subtractExact(qoy, 1), 3L))
date = date.plusDays(Math.subtractExact(doq, 1))
} else {
val qoy: Int = QUARTER_OF_YEAR.range.checkValidIntValue(qoyLong, QUARTER_OF_YEAR)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ object IsoFields {
if (resolverStyle eq ResolverStyle.LENIENT) {
val qoy: Long = qoyLong
date = LocalDate.of(y, 1, 1)
date = date.plusMonths(Math.multiplyExact(Math.subtractExact(qoy, 1), 3))
date = date.plusMonths(Math.multiplyExact(Math.subtractExact(qoy, 1), 3L))
date = date.plusDays(Math.subtractExact(doq, 1))
} else {
val qoy: Int = Field.QUARTER_OF_YEAR.range.checkValidIntValue(qoyLong, Field.QUARTER_OF_YEAR)
Expand Down
109 changes: 106 additions & 3 deletions core/shared/src/main/scala/org/threeten/bp/Duration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import java.util.regex.Pattern
import org.threeten.bp.LocalTime.SECONDS_PER_DAY
import org.threeten.bp.LocalTime.SECONDS_PER_HOUR
import org.threeten.bp.LocalTime.SECONDS_PER_MINUTE
import org.threeten.bp.LocalTime.HOURS_PER_DAY
import org.threeten.bp.LocalTime.MINUTES_PER_HOUR
import org.threeten.bp.format.DateTimeParseException
import org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND
import org.threeten.bp.temporal.ChronoUnit
Expand Down Expand Up @@ -925,7 +927,7 @@ final class Duration private (private val seconds: Long, private val nanos: Int)
def multipliedBy(multiplicand: Long): Duration =
if (multiplicand == 0) Duration.ZERO
else if (multiplicand == 1) this
else Duration.create(toSeconds.multiply(BigDecimal.valueOf(multiplicand)))
else Duration.create(toSecondsBD.multiply(BigDecimal.valueOf(multiplicand)))

/**
* Returns a copy of this duration divided by the specified value.
Expand All @@ -944,7 +946,7 @@ final class Duration private (private val seconds: Long, private val nanos: Int)
def dividedBy(divisor: Long): Duration =
if (divisor == 0) throw new ArithmeticException("Cannot divide by zero")
else if (divisor == 1) this
else Duration.create(toSeconds.divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN))
else Duration.create(toSecondsBD.divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN))

/**
* Converts this duration to the total length in seconds and fractional nanoseconds expressed as a
Expand All @@ -953,9 +955,37 @@ final class Duration private (private val seconds: Long, private val nanos: Int)
* @return
* the total length of the duration in seconds, with a scale of 9, not null
*/
private def toSeconds: BigDecimal =
private def toSecondsBD: BigDecimal =
BigDecimal.valueOf(seconds).add(BigDecimal.valueOf(nanos.toLong, 9))

/**
* Gets the number of seconds in this duration.
*
* This returns the total number of whole seconds in the duration.
*
* This instance is immutable and unaffected by this method call.
*
* @return
* the whole seconds part of the length of the duration, positive or negative
*
* @since 9
*/
def toSeconds: Long = seconds

/**
* Extracts the number of seconds part in the duration.
*
* This returns the remaining seconds when dividing toSeconds() by seconds in a minute. This is
* based on the standard definition of a minute as 60 seconds.
*
* This instance is immutable and unaffected by this method call.
*
* @return
* the number of seconds parts in the duration, may be negative
* @since 9
*/
def toSecondsPart: Int = (toSeconds % SECONDS_PER_MINUTE).toInt

/**
* Returns a copy of this duration with the length negated.
*
Expand Down Expand Up @@ -1065,6 +1095,20 @@ final class Duration private (private val seconds: Long, private val nanos: Int)
*/
def toDays: Long = seconds / SECONDS_PER_DAY

/**
* Extracts the number of days in the duration.
*
* This returns the total number of days in the duration by dividing the number of seconds by
* 86400. This is based on the standard definition of a day as 24 hours.
*
* This instance is immutable and unaffected by this method call.
*
* @return
* the number of days in the duration, may be negative
* @since 9
*/
def toDaysPart: Long = seconds / SECONDS_PER_DAY

/**
* Gets the number of hours in this duration.
*
Expand All @@ -1078,6 +1122,20 @@ final class Duration private (private val seconds: Long, private val nanos: Int)
*/
def toHours: Long = seconds / SECONDS_PER_HOUR

/**
* Extracts the number of hours part in the duration.
*
* This returns the number of remaining hours when dividing toHours() by hours in a day. This is
* based on the standard definition of a day as 24 hours.
*
* This instance is immutable and unaffected by this method call.
*
* @return
* the number of hours part in the duration, may be negative
* @since 9
*/
def toHoursPart: Int = (toHours % HOURS_PER_DAY).toInt

/**
* Gets the number of minutes in this duration.
*
Expand All @@ -1091,6 +1149,20 @@ final class Duration private (private val seconds: Long, private val nanos: Int)
*/
def toMinutes: Long = seconds / SECONDS_PER_MINUTE

/**
* Extracts the number of minutes part in the duration.
*
* This returns the number of remaining minutes when dividing toMinutes() by minutes in an hour.
* This is based on the standard definition of an hour as 60 minutes.
*
* This instance is immutable and unaffected by this method call.
*
* @return
* the number of minutes parts in the duration, may be negative
* @since 9
*/
def toMinutesPart: Int = (toMinutes % MINUTES_PER_HOUR).toInt

/**
* Converts this duration to the total length in milliseconds.
*
Expand All @@ -1111,6 +1183,22 @@ final class Duration private (private val seconds: Long, private val nanos: Int)
Math.addExact(result, nanos.toLong / Duration.NANOS_PER_MILLI)
}

/**
* Extracts the number of milliseconds part of the duration.
*
* This returns the milliseconds part by dividing the number of nanoseconds by 1,000,000. The
* length of the duration is stored using two fields - seconds and nanoseconds. The nanoseconds
* part is a value from 0 to 999,999,999 that is an adjustment to the length in seconds. The total
* duration is defined by calling getNano() and getSeconds().
*
* This instance is immutable and unaffected by this method call.
*
* @return
* the number of milliseconds part of the duration.
* @since 9
*/
def toMillisPart: Int = (nanos / Duration.NANOS_PER_MILLI).toInt

/**
* Converts this duration to the total length in nanoseconds expressed as a {@code long}.
*
Expand All @@ -1127,6 +1215,21 @@ final class Duration private (private val seconds: Long, private val nanos: Int)
Math.addExact(result, nanos.toLong)
}

/**
* Get the nanoseconds part within seconds of the duration.
*
* The length of the duration is stored using two fields - seconds and nanoseconds. The
* nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to the length in
* seconds. The total duration is defined by calling getNano() and getSeconds().
*
* This instance is immutable and unaffected by this method call.
*
* @return
* the nanoseconds within the second part of the length of the duration, from 0 to 999,999,999
* @since 9
*/
def toNanosPart: Int = nanos

/**
* Compares this duration to the specified {@code Duration}.
*
Expand Down
120 changes: 120 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
inputs = {
typelevel-nix.url = "github:typelevel/typelevel-nix";
nixpkgs.follows = "typelevel-nix/nixpkgs";
flake-utils.follows = "typelevel-nix/flake-utils";
};

outputs = { self, nixpkgs, flake-utils, typelevel-nix }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs-x86_64 = import nixpkgs { system = "x86_64-darwin"; };
scala-cli-overlay = final: prev: { scala-cli = pkgs-x86_64.scala-cli; };
pkgs = import nixpkgs {
inherit system;
overlays = [ typelevel-nix.overlay scala-cli-overlay ];
};
in {
devShell = pkgs.devshell.mkShell {
imports = [ typelevel-nix.typelevelShell ];
packages = [
pkgs.nodePackages.vscode-langservers-extracted
];
typelevelShell = {
nodejs.enable = true;
jdk.package = pkgs.jdk17;
};
};
}

);
}
Loading