java - 是否有等效于 ChronoUnit.between 的返回分数而不是整数?

标签 java java-8 java-time jsr310

ChronoUnit.HOURS.between(start, end) 等方法返回 long,因此我无法从那里获取分数。

是否有替代方法可以返回分数?

最佳答案

ChronoUnit.HOURS.between(start, end) 的重点是获取两个时间点之间的小时数。例如:两者之间有 1 或 2 小时,没有 1.5658 小时* 这样的东西。如果您需要更精确,请使用另一个 ChronoUnit,即分钟或秒。

小数的问题是,它们通常基于 10,而时间单位是基于圆(360°、2pi 等)的分数,最好用整数的分数表示,例如 1/4、1/8、1/2 等,而不是浮点值。这里的关键字是“ float ”,你可以通过移动点来表示一个值,或者将一个基值乘以 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 点四分之一”。

因此,在时间 API* 中进行小数计算没有实际用途。但如果您需要它(即出于计算目的),您可以非常简单地计算它。

如果您需要分数 - 即分钟或秒 - 您必须使用相应的 ChronoUnit,即 ChronoUnit.MINUTESChronoUnit.SECONDS,并将它除以你想要的一部分所需的时间单位。例如

  • 60 分钟等于一个小时
  • 3600 秒等于一个小时
  • 3600000 毫秒相当于一个小时,等等
  • 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 posted

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

*) 没有规则没有异常(exception):为了让事情变得困难,对于时间单位,计算基础会随着小于 1 秒的单位而变化,因为它会以 10 为基础,即毫秒(1/1000),微秒(1/1000000th),... 因此,对于秒和更小的秒数,通常使用小数,例如:1.74 秒,因为只需移动小数点分隔符即可将其转换为下一个更小的时间单位:

1.74 s <-> 1740.0 ms. 

但几个小时没那么容易:

1.74 hours <-> 104.40 minutes.

关于java - 是否有等效于 ChronoUnit.between 的返回分数而不是整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37785747/

相关文章:

java - Java 中的 'SAM type' 是什么?

java DateTimeFormatterBuilder 在测试时失败

java-8 - 获取一天中给定时间的前一个时刻

java - 无法使用 SLF4J 禁用 quartz 调度程序日志记录

java - 将反斜杠视为普通字符的一种方法

Java:变量 "might have already been initialized",但我不明白如何

java - 从内部类引用的局部变量必须是最终的或有效最终的

java - 如何将 "nested for each"转换为 Java 8 Lambda/Stream 构造?

java - 使用新的 dateTime API 获取持续时间

java - 找到最早的有效数字24小时格式时间,这可以用给定的6位数字来实现