我觉得这个问题已经以某种方式被问到了,但我仍然对我的结果没有信心。
我有一个 xsd:duration ,它将给我一个所需的到期时间,以年、月、日和秒为单位描述。我可以使用例如 duration.getYears()
或 duration.getMonths()
来收集这些部分的整数值。
因为我选择的数据库是 Cassandra,所以我想利用 TTL 选项,该选项将在指定的秒数后自动使插入的行过期。
关键部分是从 xsd:duration 获取符合公历的整数/长秒值(其中从现在开始的 1 个月不仅仅是 30.41 天,而是 31 天)。
目前,我正在使用以下代码:
LocalDateTime then = LocalDateTime.now().plusYears(duration.getYears()).plusMonths(duration.getMonths()).plusDays(duration.getDays()).plusHours(duration.getHours()).plusMinutes(duration.getMinutes()).plusSeconds(duration.getSeconds());
long ttlMillis = then.toInstant(ZoneOffset.UTC).toEpochMilli() - Instant.now().toEpochMilli();
有没有更快/更干净的方法来做到这一点?
我也不确定是否应该担心较长的持续时间...我的特定用例不会需要超过 2 年的时间。
最佳答案
给所有人的信息说明:
您正在谈论javax.xml.datatype.Duration
,而不是java.time.Duration
。
您的问题:
a) 有没有更快的方法来做到这一点(使用 Java-8)? 几乎没有。 JSR-310 团队负责 Java-8 中新的日期和时间库的设计者并不太关心与 JDK 中现有 XML 类的桥梁。因此没有直接的方法将 xml-duration 转换为任何类型的 JSR-310-duration。
还请记住,JSR-310 类 Period
(状态由年、月和日组成)和 Duration
(状态由秒和纳秒组成) )并不是真正为表示 xml-duration 而设计的(如代码中所示,它具有更多单位)。所以我怀疑将来我们是否会在 JSR-310 和 XML 之间看到一个定义明确的桥梁(也许仅以毫秒为基础?)。 JSR-310 和 XML 中的符号处理也完全不同。因此,如果 xml-duration 中有负号,请务必小心。
b) 是否有更简洁的方法来执行此操作(使用 Java-8)? 是的,有一点。 需要考虑的一件事是:我只会使用时钟作为实际瞬间的时间源一次,而不是像您所做的那样两次。这个(非常)小的改进的示例:
Instant now = Instant.now();
LocalDateTime start = now.atOffset(ZoneOffset.UTC).toLocalDateTime();
LocalDateTime end =
start.plusYears(duration.getYears())
.plusMonths(duration.getMonths())
.plusDays(duration.getDays())
.plusHours(duration.getHours())
.plusMinutes(duration.getMinutes())
.plusSeconds(duration.getSeconds());
long deltaInMillis = end.toInstant(ZoneOffset.UTC).toEpochMilli() - now.toEpochMilli();
要考虑的第二件事: xml-duration 类设计用于与 java.util.Date
进行互操作。所以你还有这个简短的选择:
Date start = new Date();
long deltaInMillis = duration.getTimeInMillis(start);
这种替代方案不仅更短,而且可能也更精确,因为它考虑了毫秒部分。根据documentation如果您的持续时间项目在长范围内(超出 int 的范围),您只需担心正确性。另一个主题是与任何隐藏时区计算的关系。我没有在文档中看到任何提示,所以这可能是唯一会让您担心的项目(本地时区?或 UTC? - 未测试)。
c) 为什么要担心大的持续时间? 即使你的持续时间比可能跨越历史公历的有效性限制的几个世纪还要长,你也应该记住 xml-duration 仅使用预言性公历,而不是历史历。 LocalDateTime
也使用相同的预推公历。然而,如果这么长的持续时间与任何真实数据相关,则是另一个好问题。
关于Java 8 -- 如何使用 xsd :duration 计算从现在开始的(毫秒)秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26040592/