【问题标题】:Round instant with more than 6 digits (nanoseconds) after comma逗号后超过 6 位(纳秒)的整数
【发布时间】:2021-12-02 02:39:38
【问题描述】:

我有带有 TIMESTAMP 字段的 postgresql,它具有带有日期和时间的 Instant。例如:2021-10-13T15:04:24.944921Z

如您所见,逗号后有 6 位数字 - 944921。但是如果我有更多的数字,例如:2021-10-13T07:14:47.791616921Z。我怎样才能正确地将这样的Instant 舍入到2021-10-13T07:14:47.791617Z

【问题讨论】:

  • 我不会关注文本表示,而是你想要做的事情。听起来您正试图在秒内四舍五入到整数微秒。我建议您使用Instant.getNano() 来查找秒内的纳秒数,使用% 运算符来查找“微秒的纳秒”并减去那么多纳秒...
  • 或者,如果您实际上对文本表示感兴趣,则可以使用仅格式化为微秒的适当格式化程序。有点不清楚您要达到的目标。
  • @JonSkeet 我想到了文本格式解析器。看起来 java API 不支持 truncatedTo(ChronoUnit.MICROS) 方法。
  • 您是要解析还是格式化?同样,您的问题还不清楚 - 我之前没有发现 truncatedTo 方法,但这应该很容易。当你说“看起来那个 java API 不支持这样的东西”时,你到底是什么意思?您可以越清楚地提出问题,包括您尝试过的内容和发生的事情越好。
  • @JonSkeet 关于成就。我在数据库中有一个时间戳,它在日期和时间格式的逗号后面有固定的位数。非常重要的是,这些日期会自动四舍五入。因此,它们在逗号后四舍五入,如上例所示。但是 JPA 会在逗号后产生 9 位数字的瞬间(日期和时间),而不是 6 位。我想对其进行舍入。

标签: java datetime timestamp rounding java.time.instant


【解决方案1】:

代码很短,但需要一些解释。你是对的,我们最好的方法是 truncatedTo 方法,它总是向下取整。相反,我们想要我们在学校学到的半数四舍五入:如果第 7 位小数为 4 或更少,则向下舍入。如果是 5 或更高,则向上取整。

为了获得这个,我首先添加 500 纳秒。然后截断。如果第 7 位小数是 4 或更少,它仍然是 9 或更少,所以它之前的数字没有改变,截断将做我们想要的四舍五入。如果第 7 位小数为 5 或更大,则添加 500 纳秒将溢出,第 6 位小数将增加 1,第 7 位小数将在 0 到 4 范围内结束。然后截断将有效地对我们想要的原始值进行四舍五入。

    Instant sourceValue = Instant.parse("2021-10-13T07:14:47.791616921Z");
    Instant rounded = sourceValue.plusNanos(500).truncatedTo(ChronoUnit.MICROS);
    System.out.println(rounded);

输出是期望的:

2021-10-13T07:14:47.791617Z

让我们也试试边缘情况。

    Instant sourceValue = Instant.parse("2021-10-13T07:14:00.000000499Z");

2021-10-13T07:14:00Z

    Instant sourceValue = Instant.parse("2021-10-13T07:14:59.999999500Z");

2021-10-13T07:15:00Z

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-31
    • 2021-10-30
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多