【译】一文精通 Java 8 时间
一、背景: 为什么新 API
首先,介绍为什么需要创建新的 API。
1.1 java.util.Date 的问题
- 非确定(固定)的 – 日期实例不是不可变的。
- 存在并发性问题 – 日期实例是非线程安全的。
- 不正确的命名 – Date 不是“日期”,而是“时间戳”(译者注:“泰山”不是泰山,而是一只大猩猩)。
- 缺乏约定(规范) – 天从1开始,月从0开始,年从1900开始(译者注:这是很让人摸不着头脑的)。
- 不连续(缺乏“流畅”性) – 不能创建“持续时间”(比如:一个季度、5分钟)或组合(比如:年+月、没有秒的日期)等。
System.currentTimeInMillis()
是不准确的,该 API 可以为多个连续调用返回相同的值。java.util.Date
vsjava.sql.Date
–java.sql.Date
只是一个没有时间的 Date。java.sql.Timestamp
–java.sql.Timestamp
复制的java.util.Date
添加了纳秒的存储。
- 缺乏清晰度 – 混合了日期和时间。
- 有混乱的时区支持 – 不太容易切换时区、偏移量等。
- 存在严重的格式障碍 –
SimpleDateFormat
和Calendar
不能很好地互操作。 - 带来了扩展的困难 – 难以通过扩展
Calendar
创建新的日历系统。
二、解决方案? 2.1 JSR-310: Date and Time API 摘自 JSR-310 (https://jcp.org/en/jsr/detail...
- 主要目标是基于 Java SE 中前两个 API (
Date
和Calendar
) 的经验教训,为日期和时间操作提供一个更高级、更全面的模型。 - 新的 API 将针对所有需要日期和时间数据模型的应用程序。这个模型将超越类,取代
Date
和Calendar
,包括没有时间的日期、没有日期的时间、持续时间和间隔的表示。 - 新的 API 还将解决相关的日期和时间问题。其中包括 格式化和解析,考虑到 ISO8601 标准 以及它的实现,例如 XML。
- 新API的最终目标是易于使用。API 将需要包含一些强大的特性,但是不能让这些特性掩盖标准用例。易于使用的一部分包括与现有的
Date
和Calendar
类的交互……
JSR-310
的“灵感来自”斯蒂芬·科尔伯恩**\_(Stephen Colebourne) \_**的非常流行的 Joda-Time 库,他也是JSR-310
的领导者。JSR-310
是一种既克服缺点又重构 Joda-Time 部分的方法。http://blog.joda.org/2009/11/...\_4941.html.- 检查从
Joda-Time
转换到Java.time
的 API:http://blog.joda.org/2014/11/... - 还可以在 stackoverflow 上查看 Meno Hochschild (Time4J 库的作者)的回答:http://stackoverflow.com/ques...
类名 | 说明 |
---|---|
Instant |
存储来自 Java 纪元的时间戳 + 纳秒 |
LocalDate |
存储没有时间部分的日期(日历日期) |
LocalTime |
存储没有日期部分的时间(挂钟) |
LocalDateTime |
存储日期和时间(LocalDate + Local Time) |
ZonedDateTime |
存储带有时区的日期和时间 |
OffsetTime |
存储时间和与 UTC 的偏移量 |
OffsetDateTime |
存储带有时间和 UTC 偏移量的日期 |
类名 | 说明 |
---|---|
Duration |
以纳秒为单位为时间。(例如:5 分钟) |
Period |
以年、月和(或)天为单位的时间。(例如:2 天) |
Month |
存储月份。(例如:MARCH 三月) |
MonthDay |
存储没有年份或时间的月份和日期(例如:出生日期) |
Year |
存储年份。(例如:2015) |
YearMonth |
存储没有日期或时间的年和月。(例如:信用卡有效期) |
DayOfWeek |
单独存储一周中的某一天。(例如:WEDNESDAY 星期三) |
类名 | 说明 |
---|---|
Chronology |
是创建或获取预建日历系统的工厂默认为 IsoChronology (例如:ThaiBuddhistChronology ) |
ChronoLocalDate |
在任意年表中存储没有时间的日期 |
ChronoLocalDateTime |
以任意年表存储日期和时间 |
ChronoZonedDateTime |
以任意年表形式存储日期、时间和时区 |
ChronoPeriod |
模拟天/时间跨度以用于任意年表 |
Era |
存储时间线 [通常两个 Chronology,但有时会更多] |
文章图片
Ranges:
文章图片
Partials:
文章图片
五、流式和语义化的 API Java 8 日期时间 API 在操作中引入了某种对称性,从而为开发人员带来愉快的编程体验。下面是 API 中通用的方法的前缀列表。
- of {类工厂方法前缀} – 使用提供的参数构造一个对象——验证和构造不进行转换。示例:
LocalDate.of(...)
orInstant.ofEpochSecond(...)
- from {类工厂方法前缀} – 使用提供的参数构造一个对象——验证、转换和构建。示例:
LocalDateTime.from(...)
orOffsetTime.from(...)
- parse {类工厂方法前缀} – 通过解析提供的 CharSequence 参数获得对象。示例:
LocalDate.parse(...)
orOffsetDateTime.parse(...)
- format {对象方法前缀} – 使用给定的时间格式参数格式化对象。示例:
localDate.format(formatter)
- get {对象方法前缀} – 返回目标时间对象的部分状态。示例:
localDate.getDayOfWeek()
- is {对象方法前缀} – 查询目标时间对象的部分状态。示例:
localTime.isAfter(...)
- with {对象方法前缀} – 对部分进行更改返回不可变时态对象的一个副本。示例:
offsetTime.withHour(...)
- plus {对象方法前缀} – 返回具有添加时间的时间对象的副本。示例:
localDate.plusWeeks(...)
- minus {对象方法前缀} – 返回时间对象减去时间的副本。示例:
localTime.minusSeconds(...)
- to {对象方法前缀} – 将时间对象转换为另一种类型的新时间对象。示例:
localDateTime.toLocalDate(...)
- at {对象方法前缀} – 使用提供的参数将时间对象组合成一个新的时间对象 。示例:
localDate.atTime(...)
JustAuth
、Jap
作者)、李寻欢(Pig
团队)。【【译】一文精通 Java 8 时间】这篇文章躺在译文列表里有一年多了,眼看
Java17
即将发布,然而大部分同学对 Java8
时间仅仅掌握了个皮毛,故翻译出来,希望对大家有所帮助。另外欢迎关注我们 JAVA架构日记,我们会定期整理、翻译业内文章和梳理热门软件更新。另外我们团队开源有 Pig、SpringBlade、Avue、JustAuth、IJPay 和 Mica 等热门项目,欢迎 star!!!
推荐阅读
- 宽容谁
- 我要做大厨
- 增长黑客的海盗法则
- 画画吗()
- 2019-02-13——今天谈梦想()
- 远去的风筝
- 三十年后的广场舞大爷
- 叙述作文
- 20190302|20190302 复盘翻盘
- 学无止境,人生还很长