2

私は午前中ずっと、比較的簡単な作業だと最初に思っていたものを達成する方法を見つけようとして過ごしました。数値で表された期間を読みやすい方法に変換します。たとえば、入力が3.5の場合、出力は「3年6か月」になります。

私が読んでいたことによると、JodaTimeライブラリが強く推奨されているようです。そのライブラリを使用し、この投稿に従って、私は次のようなことを試みていました。

    Period p = new Period(110451600000L); // 3 years and a half

    PeriodFormatter formatter = new PeriodFormatterBuilder()
        .appendYears()
        .appendSuffix(" year", " years")
        .appendSeparator(" and ")
        .appendMonths()
        .appendSuffix(" month", " months")
        .toFormatter();

    System.out.println(formatter.print(p));

しかし、出力は何もありません。なぜそれが機能しないのか分かりません。

Apache durationFormatUtilsも試してみましたが、機能しません。

誰かアイデアがありますか?

前もって感謝します。

4

2 に答える 2

4

いくつかの調査、テスト、およびベンジャミンの助けを借りて、解決策があります。

    DateTime dt = new DateTime(); // Now
    DateTime plusDuration = dt.plus(new Duration(110376000000L)); // Now plus three years and a half

    // Define and calculate the interval of time
    Interval interval = new Interval(dt.getMillis(), plusDuration.getMillis());

    // Parse the interval to period using the proper PeriodType
    Period period = interval.toPeriod(PeriodType.yearMonthDayTime());

    // Define the period formatter for pretty printing the period
    PeriodFormatter pf = new PeriodFormatterBuilder()
            .appendYears().appendSuffix("y ", "y ")
            .appendMonths().appendSuffix("m", "m ").appendDays()
            .appendSuffix("d ", "d ").appendHours()
            .appendSuffix("h ", "h ").appendMinutes()
            .appendSuffix("m ", "m ").appendSeconds()
            .appendSuffix("s ", "s ").toFormatter();

    // Print the period using the previously created period formatter
    System.out.println(pf.print(period).trim());

Joda -Time の公式ドキュメントと、特にこの投稿が非常に役立つことがわかりました: JodaTime を使用して期間を正しく定義する

それにもかかわらず、それは機能していますが、上記の投稿されたコードの出力が「3y 6m 11h」であり、これらの11時間の理由が理解できないため、100%満足していません:Sとにかく、年と数か月なので、大きな問題ではないと思います。理由や特定のシナリオで問題になる可能性があるかどうかを誰かが知っている場合は、コメントでお知らせください。

于 2012-09-10T09:52:24.203 に答える
2

コードのピリオドpには年または月が含まれていないため、フォーマッタは何も出力しません。formatter を使用するPeriodFormat.getDefault()と、時間、つまり正確に 30681 = 110451600000 / 1000 / 60 / 60 が含まれていることがわかります。

これが理由です。ミリ秒は、定義された方法で秒、分、時間に変換できます。しかし、日数、月数、または年数の計算はあいまいです。1 日の時間数が異なる可能性があるため (タイム ゾーンのシフト)、1 か月の日数や 1 年の日数も異なる可能性があるためです。ドキュメントを参照してください: http://joda-time.sourceforge.net/apidocs/org/joda/time/Period.html#Period%28long%29

そこにあるように:

変換プロセスをより詳細に制御するには、次の 2 つのオプションがあります。

  • 期間を間隔に変換し、そこから期間を取得します
  • 日付の正確な定義と、UTC などのより大きなフィールドを含む期間タイプを指定します。
于 2012-09-03T14:02:31.887 に答える