Duration
の新しいクラス JSR 31 date API( Java.time package )はJava 8以降、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)
それでは、期間オブジェクトから分と時間を抽出する推奨される方法は何ですか?秒数から計算する必要がありますか?なぜそのように実装されたのですか?
「なぜそのように実装されたのですか?」
他の答えは、時間/分を照会できるtoXxx()
メソッドに関するものです。私はその理由に対処しようとします。
TemporalAmount
インターフェースとget(TemporalUnit)
メソッドは、プロセスのかなり後期に追加されました。私は個人的に、その領域で設計を行うための正しい方法の十分な証拠があるとは完全に確信していませんでしたが、TemporalAmount
を追加するためにわずかにひねりました。そうすることで、APIを少し混乱させたと思います。
後から考えると、TemporalAmount
には適切なメソッドが含まれていると思いますが、get(TemporalUnit)
には別のメソッド名が付いているはずです。理由は、get(TemporalUnit)
は本質的にフレームワークレベルのメソッドであり、日常的に使用するために設計されていないためです。残念ながら、メソッド名get
はこれを意味しないため、Duration
でget(ChronoUnit.MINUTES)
を呼び出すようなバグが発生します。
したがって、get(TemporalUnit)
を考える方法は、量を_Map<TemporalUnit, Long>
_として表示する低レベルのフレームワークを想像することです。ここで、Duration
はサイズ2のMap
ですSECONDS
およびNANOS
のキーを使用します。
同様に、Period
は、低レベルのフレームワークから、サイズ3のMap
として表示されます-DAYS
、MONTHS
、およびYEARS
(幸いなことにエラーの可能性は低くなります)。
全体として、アプリケーションコードの最善のアドバイスは、メソッドget(TemporalUnit)
を無視することです。代わりにgetSeconds()
、getNano()
、toHours()
およびtoMinutes()
を使用してください。
最後に、Duration
から "hh:mm:ss"を取得する1つの方法は次のとおりです。
_LocalTime.MIDNIGHT.plus(duration).format(DateTimeFormatter.ofPattern("HH:mm:ss"))
_
まったくきれいではありませんが、1日未満の期間は機能します。
to…Part
_メソッドJDK-8142936 問題がJava 9で実装されました。Duration
の各部分にアクセスする次のメソッドを追加します。
toDaysPart
toHoursPart
toMinutesPart
toSecondsPart
toMillisPart
toNanosPart
便利なtoHours
、toMinutes
およびその他の変換方法を指摘したbigtの回答(+1)に追加したいと思います。 期間指定 の意味:
このクラスは、秒またはナノ秒の観点から量または時間をモデル化します。 [...]
期間の範囲には、長い数値より大きな数値を格納する必要があります。これを実現するために、クラスは秒を表すlongとナノ秒を表すintを格納します。これは常に0〜999,999,999です。
getSeconds
、getNano
、get(TemporalUnit)
など、さまざまなgetterメソッドがあります。期間が(秒、ナノ)のペアとして表されることを考えると、get(TemporalUnit)
が秒とナノに制限される理由は明らかです。これらのゲッターメソッドは期間インスタンスから直接データを抽出し、ロスレスです。
対照的に、toDays
、toHours
、toMillis
toMinutes
、およびtoNanos
を含むさまざまなtoメソッドがあります期間値の変換。これらの変換は、データの切り捨てを伴うという点で損失が大きく、要求された形式で期間値を表現できない場合は例外をスローする可能性があります。
Getメソッドが変換なしでデータを抽出し、toメソッドが何らかの変換を実行することは、明らかに設計の一部です。
「正規化された」方法で時間/分/秒コンポーネントを取得するには、それらを手動で計算する必要があります-以下のコードは基本的に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);
Hourseを削除してから分を取得
long hours = attendanceDuration.toHours(); long minutes = attendanceDuration.minusHours(hours).toMinutes();