web-dev-qa-db-ja.com

Java 8 / jsr310で期間をフォーマットする

プロジェクトをJoda-TimeからJava8のネイティブタイムライブラリに移行していますが、思わぬ障害に遭遇しました。

Durationのフォーマッターが見つかりません。たとえば、HHH + MMのカスタム文字列形式を使用します。75時間15分の期間は"75 + 15"の形式になります。

これは、期間に変換し、PeriodFormatterを使用してJoda-Timeで簡単に実行できましたが、Java8でこのタイプのクラスを見つけることができませんでした。何か不足していますか?

36
Chad Lowe

JodaTimeとは異なり、jsr-310には期間/期間フォーマッターはありません。 JodaTimeのすべての機能がJSR-310に移植されたわけではありません(たとえば、PeriodTypeもありません)。また、逆にJSR-310には、JodaTimeでは利用できない機能がいくつかあります(たとえば、ローカライズされた平日番号や、調整機能を使用した戦略パターンアプローチなど)。

Java 9は、ある種の組み込みのピリオドフォーマットを導入します(これについてはS. Colebourneから読んでください)。

結論:JSR-310とJodaTimeは互いに完全に互換性がないため、多くの作業が必要になる場合があります。できるだけ早く移行に熱心ではありません。 JodaTimeが提供していないJSR-310の特別な機能が必要ですか?

追記:また、joda期間(年から秒までのすべてのユニットを含む)はjsr310-period(年、月、日のみ)またはjsr310-duration(時間、分のみ、秒および小数秒)。

20
Meno Hochschild

Java 9以降:_Duration::to…Part_メソッド

In Java 9 the Duration class 獲得した新しい_to…Part_メソッド 日のさまざまな部分を返すため、時間、分、秒、ミリ秒/ナノ秒これを参照してください プレリリースOpenJDKソースコード

49H30M20.123Sの期間を指定すると…

  • toNanosPart() = 123000000
  • toMillisPart() = 123
  • toSecondsPart() = 20
  • toMinutesPart() = 30
  • toHoursPart() = 1
  • toDaysPart() = 2

ここで「日」とは、カレンダーの日付を無視して24時間単位の塊を意味することを忘れないでください。日付を気にする場合は、代わりに Period classを使用してください。

フォーマッタ機能が追加されているかどうかはわかりません。しかし、少なくとも、これらの新しいゲッターメソッドを介して取得した数値から、より便利に独自の文字列を生成できます。

Java 8

奇妙なことに、これらの値の便利なゲッターメソッドは、Java.timeの初版リリースにJava 8.で含まれていません。Java.timeフレームワーク。

関連する質問を参照してください: なぜJava.timeで時間を分または時間単位で取得できないのですか?

27
Basil Bourque

組み込みの方法はありませんが、時間/分を手動で計算しなくてもアクセスできます。特定の形式は次のようになります。

Duration d = Duration.of(75, HOURS).plusMinutes(15);
long hours = d.toHours(); //75
long minutes = d.minusHours(hours).toMinutes(); //15
String HH_PLUS_MM = hours + "+" + minutes; //75+15
System.out.println(HH_PLUS_MM);

期間が24時間未満であることが保証されている場合は、次のトリックも使用できます。

String hhPlusMm = LocalTime.MIDNIGHT.plus(d).format(DateTimeFormatter.ofPattern("HH+mm"));
19
assylias

commons-lang3-timeの DurationFormatUtils を使用できます(形式はSimpleDateFormatと同じであるため、「mm」を使用する必要があります):DurationFormatUtils.formatDuration(interval.toMillis(), "HHH+mm")

悲しいことに、空の部分を除外する方法を見つけられませんでした。私の場合、日または時間は0になる可能性があるので、私はまだ自分自身をロールしなければなりませんでした。

更新: Apache commons.lang.time.DurationFormatUtils JIRAでのこの問題 を開きました。

8
Gregor

これは古い質問であることは知っていますが、最近同じことが起こりました。 shouldこれよりも良い解決策がありますが、これは私にとってはうまくいきました:

public static String millisToElapsedTime(long millis){
    DateFormat fmt = new SimpleDateFormat(":mm:ss.SSS");
    fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
    return (millis/3600000/*hours*/)+fmt.format(new Date(millis));
}

次に、これを追加できます。

public static String durationToElapsedTime(Duration d){
    return millisToElapsedTime(d.toMillis());
}
1
CodeBlind