几年前,我发表了一篇博文“The Highly Useful Java TimeUnit Enum”,其中介绍了 JDK 5 引入的 TimeUnit 枚举。 JDK 8 引入了一个更新的枚举,ChronoUnit,它比 TimeUnit
更适合并发以外的上下文,例如日期/时间操作。
java.time.temporal 包 中的ChronoUnit
类实现了TemporalUnit 接口,该接口被广泛使用在 非常需要 JDK 8 引入的 Date/Time API 中。博客文章“Java 8 中日期之间的天数”演示了使用此类来计算两个 Temporal 实例之间的时间段。
博文“Java 9。‘永远’是硬编码的地方。”着眼于 JDK 9 的“TimeUnit 类中的两个新方法”。这些方法,toChronoUnit() 和 of(ChronoUnit),支持将 TimeUnit
翻译成 ChronoUnit
以及将 ChronoUnit
翻译成 TimeUnit
。并非 ChronoUnit
中的所有值都可以转换为 TimeUnit
中的等效值,在这种情况下会抛出 IllegalArgumentException。
ChronoUnit
中每个值的 Javadoc 注释描述了每个值代表的时间单位。但是,对于 ChronoUnit
中的每个值返回什么 Duration 对我来说很有趣。以下代码片段会将这些 Duration
的 toString()
表示写入 ChronoUnit
枚举中所有值的标准输出。
显示 ChronoUnits 的持续时间
for (final ChronoUnit unit : ChronoUnit.values()) { final Duration duration = unit.getDuration(); out.println(unit + ": " + duration + " (" + duration.getSeconds() + " seconds)"); }
执行时,上述代码会产生以下输出:
Nanos: PT0.000000001S (0 seconds) Micros: PT0.000001S (0 seconds) Millis: PT0.001S (0 seconds) Seconds: PT1S (1 seconds) Minutes: PT1M (60 seconds) Hours: PT1H (3600 seconds) HalfDays: PT12H (43200 seconds) Days: PT24H (86400 seconds) Weeks: PT168H (604800 seconds) Months: PT730H29M6S (2629746 seconds) Years: PT8765H49M12S (31556952 seconds) Decades: PT87658H12M (315569520 seconds) Centuries: PT876582H (3155695200 seconds) Millennia: PT8765820H (31556952000 seconds) Eras: PT8765820000000H (31556952000000000 seconds) Forever: PT2562047788015215H30M7.999999999S (9223372036854775807 seconds)
上面显示的每个 Duration
的字符串表示形式上的“PT”前缀表示该表示形式是“周期”持续时间指定(“P”)和“时间”指定(“T”)根据 ISO-8601 标准。 “S”、“M”和“H”分别是秒、分和小时。 ChronoUnit
的值表示小于一秒的时间单位(NANOS、MICROS 和MILLIS)显示“ 0 秒”,因为它们小于 1 秒,返回值为整数 long
。
ChronoUnit
类中定义的每个值的 Javadoc 注释都写得很好。它们遵循我心目中的 Javadoc“最佳实践”:在 Javadoc 中放置一个简洁但信息丰富的初始句子,以显示在生成的 HTML 页面的“方法摘要”部分,并在初始摘要之后的句子中放置其他有用的细节句子。例如,ChronoUnit.ERAS 的 Javadoc 注释指出,“代表纪元概念的单位。ISO 日历系统没有纪元,因此不可能将纪元添加到日期或日期时间。时代的估计持续时间被人为定义为 1,000,000,000 年。当与其他日历系统一起使用时,对单位没有限制。”加粗的句子(我加了强调)出现在“方法摘要”中,此处显示的整个文本显示在方法上方的完整解释中。
ChronoUnit
枚举中更有趣的值之一是 FOREVER。如上面代码清单的输出所示,FOREVER
值的 Duration
为“PT2562047788015215H30M7.999999999S”,对应于 2562047788015215 小时 30 分钟 7.999999999 秒。或者,正如 Grzegorz Gajos 表达的那样,“Java 将永远定义为 9 223 372 036 854 775 807 秒。即 2.92277266 × 1011 年。最好确保在时间用完之前在您的应用程序中安排 Java 升级。”
ChronoUnit.FOREVER
什么时候有用?它基于 Javadoc 的描述解释了它存在的主要原因:“代表永恒概念的人造单位。这主要与 TemporalField
一起使用来表示无限制的字段,例如年份或纪元。时代的估计持续时间被人为定义为 Duration
支持的最大持续时间。”
TimeUnit 是一个有用的枚举,用于处理 Java 的并发结构,并且可以在并发以外的上下文中使用,只要考虑到对这些其他上下文的一些严格限制。 JDK 8 引入的 ChronoUnit 是这些非并发上下文的更好枚举,专为与 JDK 8 Date/Time API 一起使用而设计
标签2: Java教程地址:https://www.cundage.com/article/jcg-highly-useful-java-chronounit-enum.html