7

そのようなメソッドはChronoUnit.HOURS.between(start, end)リターンなlongので、そこから分数を取得できません。

分数を返す代替方法/アプローチはありますか?

4

2 に答える 2

7

全体のポイントはChronoUnit.HOURS.between(start, end)、2 つのタイムポイント間の HOURS の数を取得することです。例: 1 時間または 2 時間の間隔で、1.5658 時間* というものはありません。さらに精度が必要な場合は、別の ChronoUnit、つまり分または秒を使用してください。

小数の問題は、通常は 10 に基づいているのに対し、時間単位は円 (360°、2pi など) に基づく分数であり、1/4、1/8、1 などの整数の分数でより適切に表現されることです。 /2 などであり、浮動小数点値ではありません。ここでのキーワードは「浮動小数点」です。ポイントを移動するか、基数に 10 のべき乗を掛けて、単位にプレフィックスを使用して値を表すことができます (つまり、1.5 * 10^3 == 1500000 * 10^-3 、ここで 10^3 はキロ、10^-3 はミリ)、しかし、日、時間、分、秒ではそれを行うことはできません。キロアワーやミリ日などというものは存在せず、単純に 10 のべき乗を掛けて時間を分に変換することはできません*。

実生活では、「1 時間と 8.3% です」または「6.5 時間後です」と言う人は誰もいません。これは通常、混乱してしまうためです (6.30 対 6:30)。「1 時間と 5 分です」または「 x から 5 度」または「x までの 4 分の 1」。

そのため、時間 API* で小数の計算を行うことは実際には実用的ではありません。しかし、それが必要な場合 (計算目的など) は、非常に簡単に計算できます。

分数または秒数が必要な場合は、対応するChronoUnit、つまりChronoUnit.MINUTESまたはを使用ChronoUnit.SECONDSして、分数を取得する全体に必要な時間単位で割る必要があります。例えば

  • 60分で1時間
  • 3600秒で1時間
  • 3600000 ミリ秒で 1 時間など。
  • 1分は60秒
  • ...

簡単な数学を使用して、分精度で分数を計算できます。

double fracH = (double)ChronoUnit.MINUTES.between(start,end) / 60;

代わりに、メソッドDurationを提供するものも使用できbetweenます。期間は、分、時間などに簡単に変換できます。

Duration dur = Duration.between(start, end);
double fracH = (double)dur.toMinutes() / 60;

最高の精度を得るには、最小の時間単位、つまりナノまたはミリで分数を計算する必要があります

double fracHns = (double)dur.toNanos() / 3_600_000_000_000;

Durationベース (100%) 値を取得するために使用することもできます。

//fraction of an hour
double fracHns = (double)dur.toNanos() / Duration.ofHours(1).toNanos();

//fraction of a minute
double fracMns = (double)dur.toNanos() / Duration.ofMinutes(1).toNanos();

またはより一般的に、David SNが投稿したように

TemporalUnit unit = ChronoUnit.HOURS;
double frac = (double)Duration.between(start, end).toNanos() 
              / Duration.of(1, unit).toNanos();

*) 例外のないルール: 難しいことに、時間単位の場合、1 秒未満の単位の計算ベースが変わります。これは、10 ベース、つまりミリ秒 (1/1000)、マイクロ秒 (1/1000000) になるためです。 ,... したがって、秒以下の場合は小数を使用するのが一般的です。たとえば、1.74 秒です。これは、小数点区切り記号を移動するだけで、次に小さい時間単位に簡単に変換できるためです。

1.74 s <-> 1740.0 ms. 

しかし、それは何時間も簡単ではありません。

1.74 hours <-> 104.40 minutes.
于 2016-06-13T09:22:38.533 に答える
2

ChronoUnit特定の時間単位で時差の 10 進値を取得するメソッドはありません。

この機能を実装するユーティリティ メソッドを作成できます。クラスDurationはこの目的に使用できます。これは、最小単位の差を取得し、それを (10 進数で) 必要な単位に変換することで実行できます。

public static double between(Temporal startInclusive, Temporal endExclusive, ChronoUnit unit) {
    Duration duration = Duration.between(startInclusive, endExclusive);
    long conversion = Duration.of(1, unit).toNanos();
    return (double) duration.toNanos() / conversion;
}
于 2016-06-13T11:04:30.843 に答える