前言
Java8之前我们使用Date
和Calendar
这两个类处理时间,但有的特性只在某一个类有提供,比如用
于以语言无关的方式格式化和解析日期或时间的DateFormat方法就只在Date类里有。DateFormat方法也有它自己的问题。
比如,它不是线程安全的。这意味着两个线程如果尝试使用同一个formatter解析日期,你可能会得到无法预期的结果。
最后,Date和Calendar类都是可以变的。能把2014年3月18日修改成4月18日意味着什么呢?
这种设计会将你拖入维护的噩梦,接下来我们从最基本的用例入手,比如创建同时适合人与机器的日期和时间,逐渐转入到日期和时间API更高级的一些应用,比如
操纵、解析、打印输出日期-时间对象,使用不同的时区。
JDK1.8提供的日期处理类都是不可变对象,所以是线程安全的。
使用 LocalDate 和 LocalTime
开始使用新的日期和时间API时,你最先碰到的可能是LocalDate类。该类的实例是一个不可变对象,它只提供了简单的日期,并不含当天的时间信息。另外,它也不附带任何与时区相关
的信息。
创建一个LocalDate对象并读取其值 :
@Test
public void testLocalDateOf() {
LocalDate localDate = LocalDate.of(2017, 12, 12);
int year = localDate.getYear();
int month = localDate.getMonthValue();
int day = localDate.getDayOfWeek().getValue();
int maxLength = localDate.getMonth().maxLength();
int minLength = localDate.getMonth().minLength();
boolean isLeap = localDate.isLeapYear();
System.out.println("TimeTest.testLocalDateOf year: " + year + "\tmonth: " + month + "\tday: " + day
+ "\tmaxLength: " + maxLength + "\tminLength: " + minLength + "\tisLeap: " + isLeap);
}
获取当前的日期:
LocalDate now = LocalDate.now();
使用TemporalField读取LocalDate的值
TemporalField
是一个接口,它定义了如何访问temporal对象某个字段的值。ChronoField
枚举类实现了这一接口,所以你可以很方便地使用get方法得到枚举元素的值:
@Test
public void testTemporalField() {
LocalDate localDate = LocalDate.of(2017, 12, 12);
int year = localDate.get(ChronoField.YEAR);
int month = localDate.get(ChronoField.MONTH_OF_YEAR);
int day = localDate.get(ChronoField.DAY_OF_MONTH);
System.out.println("TimeTest.testTemporalField year: " + year + "\tmonth: " + month + "\tday: " + day);
}
创建LocalTime并读取其值
@Test
public void testLocalTime() {
LocalTime time = LocalTime.of(14, 22, 28);
int hour = time.getHour();
int minute = time.getMinute();
int second = time.getSecond();
System.out.println("TimeTest.testLocalTime hour: " + hour + "\tminute: " + minute + "\tsecond: " + second);
}
LocalDate和LocalTime都可以通过解析代表它们的字符串创建。使用静态方法parse
:
LocalDate date = LocalDate.parse("2017-12-12");
LocalTime time = LocalTime.parse("14:22:28");
合并日期和时间
这个复合类名叫LocalDateTime
,是LocalDate和LocalTime的合体。它同时表示了日期和时间,但不带有时区信息,你可以直接创建,也可以通过合并日期和时间对象构造:
@Test
public void testLocalDateTimeCombine() {
LocalDate date = LocalDate.of(2017, 12, 12);
LocalTime time = LocalTime.of(14, 22, 28);
LocalDateTime dt1 = LocalDateTime.of(2017, Month.MARCH, 12, 14, 22, 28);
LocalDateTime dt2 = LocalDateTime.of(date, time);
LocalDa