Java 终于有了一种直观、可靠的方式来处理日期和时间。日期和时间的原则是许多应用程序的基础。出生日期、租赁日期、活动时间和商店营业时间等各种信息都基于日期和时间,但Java SE没有提供使用它们的便捷方法。从Java SE 8开始,出现了一组java.time包,它们提供了一个结构良好的API来处理日期和时间。
以下是其实施中存在的一小部分问题:
背景
当Java首次出现时,在版本1.0中,唯一用于处理日期和时间的类是java.util.Date。开发人员注意到的第一件事是它并不代表“日期”。事实上,它代表的是从 1970 年 1 月 1 日开始测量的一个时刻,精确到毫秒。然而,基于Date的toString()方法显示机器的java设置中指定的时区的日期和时间,一些开发人员错误地认为Date可以与时区一起工作。事实证明修复这个类非常困难(或者说非常懒),以至于在1.1版本中我们不得不添加一个新类 - java.util.Calendar。不幸的是,Calendar类结果并不比Date好多少。- 多变。日期和时间等类应该是不可变的。
- 偏移量。Date 中的年份从 1900 开始,两个类别中的月份都从零开始。
- 名字。Date 实际上并不是“日期”,Calendar 也不是日历。
- 格式化。格式化仅适用于日期,不适用于日历,并且不是线程安全的。
审查
新的 java.time API包含 5 个包:- java.time - 包含用于存储值的对象的基础包
- java.time.chrono - 提供对不同日历的访问
- java.time.format - 日期和时间格式化和识别
- java.time.temporal - 低级库和高级功能
- java.time.zone - 用于处理时区的类
日期
LocalDate 类是新 API中最重要的类之一。它包含一个表示日期的不可变值。您无法设置时间或时区。“local”这个名字你可能对 Joda-Time很熟悉,最初来自 ISO-8601标准。这恰恰意味着没有时区。本质上, LocalDate是对日期的描述,例如“2014 年 4 月 5 日”。该日期的实际时间将根据您所在的时区而有所不同。例如,在澳大利亚,该日期将比伦敦早 10 小时,比旧金山早 18 小时。 LocalDate类具有所有常用的方法:LocalDate date = LocalDate.of(2014, Month.JUNE, 10); int year = date.getYear(); // 2014 Month month = date.getMonth(); // Июнь int dom = date.getDayOfMonth(); // 10 DayOfWeek dow = date.getDayOfWeek(); // Вторник int len = date.lengthOfMonth(); // 30 (дней в Июне) boolean leap = date.isLeapYear(); // false (не високосный год)
在我们的示例中,我们看到使用工厂方法创建的日期(所有构造函数都是私有的)。接下来我们向对象询问一些数据。请注意,
Month和
DayOfWeek枚举旨在使代码更具可读性和可靠性。在下面的例子中我们将看到如何修改日期。由于类是不可变的,因此结果将是新对象,但原始对象将保持原样。
LocalDate date = LocalDate.of(2014, Month.JUNE, 10); date = date.withYear(2015); // 2015-06-10 date = date.plusMonths(2); // 2015-08-10 date = date.minusDays(1); // 2015-08-09
这些都是相对简单的更改,但通常您需要进行更复杂的日期修改。
java.time API中有一个特殊的机制- TemporalAdjuster 。它的目的是提供一个内置工具,允许您操作日期,例如获取与该月最后一天相对应的对象。其中一些包含在
API中,但您可以添加自己的。使用修饰符非常简单,但它需要静态导入:
import static java.time.DayOfWeek.* import static java.time.temporal.TemporalAdjusters.* LocalDate date = LocalDate.of(2014, Month.JUNE, 10); date = date.with(lastDayOfMonth()); date = date.with(nextOrSame(WEDNESDAY));
使用修饰符可以极大地简化您的代码。没有人愿意看到大量的手动日期操作。如果某种类型的日期操作在您的项目中多次发生,请编写您自己的修改器,您的团队可以将其用作已编写和测试的组件。
GO TO FULL VERSION