【问题标题】:Is Duration#toDays and Duration#toDaysPart redundant?Duration#toDays 和 Duration#toDaysPart 是多余的吗?
【发布时间】:2021-03-29 20:25:46
【问题描述】:

在 Java 8 中,Duration 类提供了 toDays 方法,以与日历天数无关的 24 小时时间块的形式返回总天数。

在 Java 9 中,Duration 类获得了方便的to…Part 方法:toDaysParttoHoursParttoMinutesParttoSecondsParttoMillisParttoNanosPart。我了解小时、分钟等的需要。但我想知道toDaysPart

我的问题是:

Duration#toDaysDuration#toDaysPart 是否会为特定的 Duration 对象返回不同的值?

【问题讨论】:

  • 我相信toSeconds()getSeconds()也是一样的。并且(回避)恕我直言,该方法系统通常名不副实。 getXxxPart 会更好,甚至只是 getXxx(),所以它与 Period.getMonths().getDays() 一致。

标签: java java-8 java-9 java-time duration


【解决方案1】:

在 Java 11 中,OpenJDK 中的这些源代码行完全相同

Duration#toDays:

public long toDays() {
    return seconds / SECONDS_PER_DAY;
}

Duration#toDaysPart

public long toDaysPart(){
    return seconds / SECONDS_PER_DAY;
}

As of Java 16,没有说明哪些已弃用,哪些未弃用。所以...睁大眼睛,这是我能给你的最好建议。

【讨论】:

  • 我怀疑是否需要弃用。我假设toDaysPart 是故意添加的,只是为了与其他to…Part 方法保持一致。感谢您找到源代码并编写答案。
  • 但它们并不太一致。所有to*Part 方法都返回一个int,而没有Part 的方法返回一个long - 除了days 方法在这两种情况下都返回一个long。这是基于 Oracle 的 src.zip 文件中 JDK 14 的源代码。
  • @WJS 返回intlong 在上下文中是有意义的。小时部分永远不会超过 23,分钟部分永远不会超过 59,依此类推。但是天数可能非常大,超过了int 的限制。例如:Duration.ofDays( Integer.MAX_VALUE + 1L ).toDaysPart() = 2147483648
  • @BasilBourque 注意超过 60 秒的分钟:'Leap Second' Tonight Will Cause 61-Second Minute
  • @AndrewMorton Leap Second 不是问题。闰秒的意义在于协调日(地球绕其轴自转)和年(地球绕太阳公转)。日子并不完全是 24 小时,而且随着地球自转速度的变化而变化。闰秒增加一秒,以使日历上的日期适合我们的太阳时。我们想假装我们的日期正好是 24 小时长。闰秒是维持这种伪装的一个软糖因素。所以关于这个答案,java.time 年表中的一天总是相同的秒数,故意忽略闰秒。
【解决方案2】:

这些方法不只是做同样的事情;他们在文档中被指定做同样的事情(在你的问题中链接):

public long toDays()

获取此持续时间的天数。 这将通过将秒数除以 86400 来返回持续时间中的总天数。这是基于一天的标准定义为 24 小时。 此实例是不可变的,不受此方法调用的影响。

返回: 持续时间的天数,可能为负数

public long toDaysPart()

提取持续时间中的天数。 这将通过将秒数除以 86400 来返回持续时间中的总天数。这是基于一天的标准定义为 24 小时。 此实例是不可变的,不受此方法调用的影响。

返回: 持续时间的天数,可能为负数

唯一的区别是描述性摘要中的“gets”与“extracts”一词。这些词在这种情况下没有不同的含义,其余的词是相同的,特别是指定方法返回的部分是相同的。事实上,toDaysPart 的 (OpenJDK) 文档是 recently changed,以澄清这些方法做同样的事情。所以是的,它们是多余的。

根据问题跟踪器上的the relevant issue,所有to...Part 方法都被添加在一起,没有任何评论表明toDaysPart 是多余的;所以我们只能推测添加冗余方法的基本原理。

【讨论】:

  • 无需推测 - 相同的公关对话使基本原理变得清晰。这些方法在概念上有所不同——前者表示持续时间以整数天为底;后者代表持续时间的天“组成部分”。由于 Duration 中内置的先决条件,它们恰好具有相同的值和实现。重复 - 是的。冗余 - 在实施中。一样 - 没有。
  • @Dave 公关对话解释了添加一堆 to...Part 方法的理由,但没有解释在此方法只能做同样事情时在其中包含 toDaysPart 的理由作为现有的toDays 方法。如果包含冗余方法有理由,我希望在 PR 对话中看到一些确认,即提议的 toDaysPart 方法是多余的,但应该包括在内,因为 [基本原理]。如果没有这个,就我们所知,添加冗余方法可能是一个疏忽。
  • 如果您碰巧在 java.time 的接口系列中实现字符串转换实用程序,这一点非常清楚。这不是疏忽。孤立地查看 Duration 时,它就不那么明显了。
【解决方案3】:

get(TemporalUnit) 继承自 TemporalAmount(以及 getSeconds() 和奇怪的名称 getNano())的目的是支持提取组合值的时间分量。 Duration 实际上只支持SECONDSNANOS 组件访问,因为Duration 只是long 秒组件和int 纳秒组件的组合,它们一起提供纳秒分辨率 em> 表示最大 2^63 秒的有向值(正数和负数)。 get_ 访问器返回只是 命名的组件,而to_ 方法返回复合整数值到目标单元。最后,Duration 上的 to_Part 方法模拟 get_ 方法的行为,如果 Duration 被想象为由每个 ChronoUnit 值的一个实例组成。此虚拟组件访问中的奇数是toDaysPart。我怀疑这样做的原因是,虽然 HOURS、MINUTES、SECONDS、MILLIS、MICROS 和 NANOS 在它们引用的组件方面可以被认为是离散和不重叠的,但在将 DAYS 视为组件值时,不清楚我们是否是指一周中的某一天、一个月中的某一天或一年中的某一天——这三个都是常见的约定。类似地,MONTHS 和 YEARS 每个都有可变长度。因此,作者似乎选择了明确的,并认为 DAYS 代表该层次结构中最粗略的组件。我个人认为这有点像狗的早餐,我想知道为什么这两种方法在得出这个结论之前有一段时间是相同的。

【讨论】:

    猜你喜欢
    • 2014-08-06
    • 2016-11-08
    • 2022-06-10
    • 2016-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多