79

DurationJava 8 以降で利用可能な新しいJSR 310日付 API ( java.time パッケージ)のクラスのうち、javadoc は次のように述べています。

このクラスは、秒単位およびナノ秒単位で量または時間をモデル化します。分や時間など、他の期間ベースの単位を使用してアクセスできます。さらに、DAYS 単位を使用でき、24 時間とまったく同じように扱われるため、夏時間の影響は無視されます。

では、なぜ次のコードがクラッシュするのでしょうか?

Duration duration = Duration.ofSeconds(3000);
System.out.println(duration.get(ChronoUnit.MINUTES));

これにより、以下が発生しUnsupportedTemporalTypeExceptionます。

java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Minutes
    at java.time.Duration.get(Duration.java:537)

では、期間オブジェクトから分と時間を抽出するための推奨される方法は何ですか? 秒数から自分で計算する必要がありますか?なぜそのように実装されたのですか?

4

6 に答える 6

37

ドキュメントには次のように記載されています。

これは、サポートされている 2 つの単位、SECONDS と NANOS のそれぞれの値を返します。他のすべてのユニットは例外をスローします。

ですから、最良の答えは、彼らが設計した方法です。

他の方法のいくつかを使用して、数時間で取得できます。

long hours = duration.toHours();

または:

long minutes = duration.toMinutes();
于 2014-06-30T13:52:55.097 に答える
12

「正規化された」方法で時間/分/秒のコンポーネントを取得するには、それらを手動で計算する必要があります。以下のコードは、基本的にDuration#toStringメソッドからコピーされたものです。

Duration duration = Duration.ofSeconds(3000);
long hours = duration.toHours();
int minutes = (int) ((duration.getSeconds() % (60 * 60)) / 60);
int seconds = (int) (duration.getSeconds() % 60);
System.out.println(hours + ":" + minutes + ":" + seconds);
于 2014-06-30T15:52:02.263 に答える
11

toHours便利な、toMinutesおよびその他の変換方法を指摘したbigtの回答(+1)に追加したいと思います。Duration 仕様には次のように記載されています。

このクラスは、秒単位およびナノ秒単位で量または時間をモデル化します。[...]

期間の範囲には、long より大きい数値を格納する必要があります。これを実現するために、クラスは long を表す秒と、常に 0 ~ 999,999,999 の間のナノ秒を表す int を格納します。

、 、 など、さまざまなgetterメソッドがあります。期間が (秒、ナノ) ペアとして表されることを考えると、秒とナノに制限される理由は明らかです。これらの getter メソッドは、duration インスタンスから直接データを抽出し、ロスレスです。getSecondsgetNanoget(TemporalUnit)get(TemporalUnit)

対照的に、期間の値を変換する、toDaystoHoursなどtoMillis toMinutesのさまざまな to メソッドがあります。これらの変換はデータの切り捨てを伴うという点で不可逆的であり、要求された形式で期間値を表すことができない場合は例外をスローする可能性があります。toNanos

get メソッドが変換せずにデータを抽出し、to メソッドが何らかの変換を実行するのは、明らかに設計の一部です。

于 2014-06-30T19:19:18.240 に答える
4

時間数を削除して分数を取得

long hours = attendanceDuration.toHours(); long minutes = attendanceDuration.minusHours(hours).toMinutes();

于 2019-02-11T13:38:02.473 に答える
-1

以下のコードにより、この期間の出力が得られました。

1日2時間5分

コード例:

private String getDurationAsString(Duration duration)
{
    StringBuilder durationAsStringBuilder = new StringBuilder();
    if (duration.toDays() > 0)
    {
        String postfix = duration.toDays() == 1 ? "" : "s";
        durationAsStringBuilder.append(duration.toDays() + " day");
        durationAsStringBuilder.append(postfix);
    }

    duration = duration.minusDays(duration.toDays());
    long hours = duration.toHours();
    if (hours > 0)
    {
        String prefix = Utils.isEmpty(durationAsStringBuilder.toString()) ? "" : ", ";
        String postfix = hours == 1 ? "" : "s";
        durationAsStringBuilder.append(prefix);
        durationAsStringBuilder.append(hours + " hour");
        durationAsStringBuilder.append(postfix);
    }

    duration = duration.minusHours(duration.toHours());
    long minutes = duration.toMinutes();
    if (minutes > 0)
    {
        String prefix = Utils.isEmpty(durationAsStringBuilder.toString()) ? "" : ", ";
        String postfix = minutes == 1 ? "" : "s";
        durationAsStringBuilder.append(prefix);
        durationAsStringBuilder.append(minutes + " minute");
        durationAsStringBuilder.append(postfix);
    }

    return durationAsStringBuilder.toString();
}

説明:

Duration インターフェースを使用すると、必要な文字列表示を簡単に見つけることができます。現在の期間からより大きな TemporalUnit を減らす必要があるだけです。

例えば:

  1. 日数を計算する
  2. 期間から日数を減らす
  3. 時間を計算する
  4. 期間などから時間を短縮します...期間= 0になるまで
于 2018-03-05T18:31:14.210 に答える