【问题标题】:Round minutes to ceiling using Java 8使用 Java 8 将分钟数逼近上限
【发布时间】:2014-08-28 14:58:56
【问题描述】:

所以我很幸运能够使用 Java 8 和新时代的 APi,但我没有看到任何舍入函数...

基本上如果时间是……

2014-08-28T10:01.00.000 ----> 2014-08-28T10:02.00.000
2014-08-28T10:01.10.123 ----> 2014-08-28T10:02.00.000
2014-08-28T10:01.25.123 ----> 2014-08-28T10:02.00.000
2014-08-28T10:01.49.123 ----> 2014-08-28T10:02.00.000
2014-08-28T10:01.59.999 ----> 2014-08-28T10:02.00.000

这似乎没问题,但对吗?

LocalDateTime now =  LocalDateTime.now(Clock.systemUTC());
LocalDateTime newTime =  now.plusMinutes(1);

System.out.println(newTime.toString());
System.out.println(newTime.format(DateTimeFormatter.ofPattern("yyyy-dd-MM'T'HH:mm:00.000")));

【问题讨论】:

  • 第一行不应该是右边的10:01吗?如果小数部分为 0,则上限函数不会更改该值。
  • 我总是想总结 :)
  • 四舍五入不会改变它。您所要求的与天花板功能略有不同。

标签: datetime java-8 rounding java-time ceil


【解决方案1】:

java.time API 不支持四舍五入,但它支持rounding to floor(截断),可以实现所需的行为(不完全四舍五入):

LocalDateTime now =  LocalDateTime.now();
LocalDateTime roundFloor =  now.truncatedTo(ChronoUnit.MINUTES);
LocalDateTime roundCeiling =  now.truncatedTo(ChronoUnit.MINUTES).plusMinutes(1);

此外,还有一个工具可以获取每分钟只滴答一次的时钟,这可能很有趣:

Clock minuteTickingClock = Clock.tickMinutes(ZoneId.systemDefault());
LocalDateTime now =  LocalDateTime.now(minuteTickingClock);
LocalDateTime roundCeiling =  now.plusMinutes(1);

这个时钟会自动将分钟截断到下限(尽管它是specified,因此它可能会返回一个延迟的缓存值)。请注意,如果需要,Clock 可以存储在静态变量中。

最后,如果这是你想在多个地方使用的常见操作,可以编写一个库TemporalAdjuster函数来执行舍入。 (调整器可以编写一次、测试并作为静态变量或方法提供)。

【讨论】:

  • 谢谢,这是我需要的。我知道我的舍入有点奇怪,但基本上我需要根据当前时间查询我的数据库系统。如果我有多个用户在当前分钟内通过四舍五入进行查询,我可以缓存过滤器! :)
  • 这个算法对于精确的分钟时间是不正确的。例如。假设当前时间正好是 5 分钟(即 0 秒、0 纳秒等)。在那种情况下,我希望 roundCeiling 为 5 分钟(即像“1.00”十进制数的上限为“1”) - 但算法将给出 6 分钟。上面的 roundCeiling 计算应检查截断值是否与“现在”相同 - 在这种情况下返回“现在”,否则返回 +1 分钟。
  • 虽然现在我注意到原始问题要求总是四舍五入(即使数字已经四舍五入),所以在这种情况下接受的答案是正确的。
【解决方案2】:
LocalDateTime newTime = now.plusMinutes(1).minusNanos(1).withSecond(0).withNano(0);

这将四舍五入到最接近的分钟,作为一个以分钟为整数部分的天花板函数。

【讨论】:

  • 简化在哪里?在大多数情况下,编写复杂的TemporalAdjuster-implementations 应仅限于框架或库编写者,而不是最终用户。这里编写调整器代码的负担仍然在用户身上。只是我的 2 美分...
  • @Meno Hochschild:你说得对,我正在通过 java.time 挖掘相关功能并最终进入库编写模式。这个问题绝对是矫枉过正。
【解决方案3】:

java.time(Java 8 中的新时间 API)与其他一些库一样没有舍入功能。您尝试使用格式化在字符串级别进行舍入。但是,如果您想对时间对象进行舍入,则可以手动进行舍入:

LocalDateTime now =  LocalDateTime.now(Clock.systemUTC());
LocalDateTime newTime =  now.plusMinutes(1).withSecond(0).withNano(0);

顺便说一句,您肯定指的是地板,而不是天花板,不是吗?

更新:

我发现这种设置为地板的更好方法(显然是唯一的舍入功能,不支持天花板):

LocalDateTime now =  LocalDateTime.now(Clock.systemUTC());
LocalDateTime newTime =  now.plusMinutes(1).truncatedTo(ChronoUnit.MINUTES);

【讨论】:

  • 我的意思是天花板,不管是 10 秒、25 秒还是 49 秒,我都想四舍五入。
猜你喜欢
  • 1970-01-01
  • 2016-01-09
  • 2010-12-25
  • 2018-04-25
  • 1970-01-01
  • 2019-05-19
  • 2021-08-12
  • 2021-08-13
  • 1970-01-01
相关资源
最近更新 更多