1. 介绍日期时间API

引入日期时间 API

Java 的创建者不喜欢 Date 和 Calendar 类的情况。他们在那个时代很好,但时代变了。并且需要一些简单、强大和可靠的东西。随着 Java 8 的发布(Calendar出现 15 年后),引入了Java Date Time API 。它是一组类,应该能够解决处理时间的每一个可能的任务。

有太多的类,它们被分成几个包:

该包是 Java 日期时间 API 的基础包:它包含、、、、和 等java.time类。这些类的所有对象都是,这意味着它们在创建后不能更改。LocalDateLocalTimeLocalDateTimeInstantPeriodDurationimmutable

java.time.format包包含用于时间格式化的类,即将时间(和日期)转换为字符串,反之亦然。例如,它包含替换类DateTimeFormatter的通用类SimpleDateFormat

java.time.zone包包含用于处理时区的类。它包含诸如TimeZone和 之类的类ZonedDateTime。如果您正在为位于世界不同地区的客户编写服务器代码,您将确实需要这些类。


2.LocalDate

我们将看到的 Date Time API 中的第一个也是最有用的类是类LocalDate。正如您可能从其名称中猜到的那样,此类旨在处理日期。

该类的对象在创建后不会改变,即该类LocalDate是不可变的。但是这个属性增加了类的简单性和可靠性。特别是当多个线程(执行线程)同时与这样的对象交互时。

要创建新LocalDate对象,您需要使用其中一种静态方法。这是主要的列表。

获取当前日期

要获取当前日期,您需要使用静态now()方法。这比看起来容易得多:

LocalDate today = LocalDate.now();

其中today是一个LocalDate变量,是对类的LocalDate.now()静态方法的调用。now()LocalDate

例子:

代码 控制台输出
LocalDate today = LocalDate.now();
System.out.println("Today = " + today);

Today = 2019-02-22

获取特定时区的日期

该类LocalDate还有一种方法的变体now(ZoneId),可让您获取特定时区的当前日期。

为此,我们需要另一个类——ZoneId类 (java.time.ZoneId)。它有一个of()方法可以返回一个ZoneId给定时区名称的对象。

判断当前上海日期,需要编写如下代码:

代码 控制台输出
ZoneId  timezone = ZoneId.of("Asia/Shanghai");
LocalDate today = LocalDate.now(timezone);
System.out.println("In Shanghai, now = " + today);


In Shanghai, now = 2019-02-22

您可以在 Internet 上找到所有时区名称的列表。


3.获取特定日期

要获取LocalDate表示特定日期的对象,您需要使用静态of()方法。这里的一切也非常简单明了:

LocalDate date = LocalDate.of(2019, Month.FEBRUARY, 22);

其中date是一个LocalDate变量,是对类的静态方法的调用。LocalDate.of()of()LocalDate

这里我们看到类FEBRUARY的常量Month(java.time.Month) 被用来指定二月作为月份。

您还可以用老式的方式指定月份——使用数字:

LocalDate date = LocalDate.of(2019, 2, 22);

二?而不是二月?这是否意味着月份再次从一开始编号?

是的,在 Java 创建近 20 年后,月份终于不再从零开始计数了。

例子:

代码 控制台输出
LocalDate today = LocalDate.of(2019, 2, 22);
System.out.println("Today = " + today);

Today = 2019-02-22

通过当天的索引获取日期

还有另一种有趣的创建日期的方法:使用该ofYearDay方法,您可以仅根据年号和年中日期的索引获取日期。这是一般外观:

LocalDate date = LocalDate.ofYearDay(year, day);

哪里year是年数,day是一年中第几天的索引。

例子:

代码 控制台输出
LocalDate today = LocalDate.ofYearDay(2019, 100);
System.out.println("Today = " + today);

Today = 2019-04-10

2019 年的第 100 天是 4 月 10 日。

获取 Unix 日期

您还记得Date对象总是将时间存储为自 1970 年 1 月 1 日以来的毫秒数吗?为了确保程序员不会错过过去的美好时光,该类LocalDate获得了一个ofEpochDay()方法,该方法返回从 1970 年 1 月 1 日开始计算的日期。这是一般外观:

LocalDate date = LocalDate.ofEpochDay(day);

day自 1970 年 1 月 1 日以来经过的天数在哪里。

例子:

代码 控制台输出
LocalDate today = LocalDate.ofEpochDay(1);
System.out.println("Today = " + today);

Today = 1970-01-02

4.获取日期元素

无法更改LocalDate对象,但您可以获得存储日期的各个元素。LocalDate对象为此有几种方法:

方法 描述
int getYear()
返回特定日期的年份
Month getMonth()
返回日期的月份:几个常量之一
JANUARY, FEBRUARY, ...;
int getMonthValue()
返回日期所在月份的索引。一月 == 1。
int getDayOfMonth()
返回一个月中的第几天的索引
int getDayOfYear()
从年初返回天的索引
DayOfWeek getDayOfWeek()
返回星期几:几个常量之一
MONDAY, TUESDAY, ...;
IsoEra getEra()
返回时代:(BCE当前时代之前)和CE(当前时代)

例子:

代码 控制台输出
LocalDate today = LocalDate.now();
System.out.println(today.getYear());
System.out.println(today.getMonth());
System.out.println(today.getMonthValue());
System.out.println(today.getDayOfMonth());
System.out.println(today.getDayOfWeek());

2019
FEBRUARY
2
22
FRIDAY

LocalDate5. 更改对象中的日期

该类LocalDate包含多个可让您处理日期的方法。这些方法的实现类似于类的方法String它们不更改现有LocalDate对象,而是返回一个包含所需数据的新对象。

以下是该类的方法LocalDate

方法 描述
plusDays(int days)
将指定的天数添加到日期
plusWeeks(int weeks)
向日期添加周数
plusMonths(int months)
将月份添加到日期
plusYears(int years)
将年份添加到日期
minusDays(int days)
从日期中减去天数
minusWeeks(int weeks)
从日期中减去周数
minusMonths(int months)
从日期中减去月份
minusYears(int years)
从日期中减去年份

例子:

代码 控制台输出
LocalDate birthday = LocalDate.of(2019, 2, 28);
LocalDate nextBirthday = birthday.plusYears(1);
LocalDate firstBirthday = birthday.minusYears(30);

System.out.println(birthday);
System.out.println(nextBirthday);
System.out.println(firstBirthday);




2019-02-28
2020-02-28
1989-02-28

我们调用的whosebirthday object方法不会改变。相反,它的方法返回包含所需数据的新对象。