前言
在Java8中引入了新的日期和时间库, 解决了Java 8 之前的库对日期和时间的支持性问题,也提供更加高级的API来适应不同的需求。
一、使用 LocalDate 和 LocalTime
LocalDate的实例是一个不可变对象,它只提供了简单的日期,并不含当天的时间信息。另外,它也不附带任何与时区相关的信息。
public void testLocalDate() {
//只包含年,月,日,包含丰富的信息
LocalDate date = LocalDate.of(2021, 7, 2);
System.out.println(date.getYear());
System.out.println(date.getMonth());
System.out.println(date.getDayOfMonth());
System.out.println(date.getDayOfWeek());
System.out.println(date.lengthOfMonth());
System.out.println(date.isLeapYear());
//也可以通过TemporalField 读取 LocalDate 的值
int year = date.get(ChronoField.YEAR);
System.out.println(year);
}
2021
JULY
2
FRIDAY
31
false
2021
类似的,LocalTime只提供简单的时间信息
public void testLocalTime() {
//只包含一天内的时间信息
LocalTime time = LocalTime.of(14, 30, 55);
int hour = time.getHour();
int minute = time.getMinute();
int second = time.getSecond();
System.out.println(hour + ":" + minute + ":" + second);
}
14:30:55
LocalDateTime = LocalDate + LocalTime。
它同时表示了日期和时间,但不带有时区信息,可以直接创建,也可以通过合并日期和时间对象创建
public void testLocalDateTime() {
//日期和时间,相当于LocalDate+LocalTime(不包含时区信息)
LocalDate date = LocalDate.of(2021, 7, 2);
LocalTime time = LocalTime.of(14, 30, 55);
//字段构建
LocalDateTime dt1 = LocalDateTime.of(2014, Month.SEPTEMBER, 21, 13, 45, 20);
//合并方式构建
LocalDateTime dt2 = LocalDateTime.of(date, time);
//传递时间对象
LocalDateTime dt3 = date.atTime(13, 45, 20);
LocalDateTime dt4 = date.atTime(time);
//传递日期对象
LocalDateTime dt5 = time.atDate(date);
//也可以从中提取LocalDate和LocalTime
LocalDate date1 = dt1.toLocalDate();
LocalTime time1 = dt1.toLocalTime();
}
二、操纵、解析和格式化日期
- 以直观方式操纵LocalDate属性
//以直观的方式操作LocalDate
LocalDate date1 = LocalDate.of(2000, 1, 23);
//在date1的基础上操作年份信息
LocalDate date2 = date1.withYear(2021);
//在date2的基础上操作日期信息
LocalDate date3 = date2.withDayOfMonth(2);
//在date3的基础上操作月份信息
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 7);
System.out.println(date4);//2021-07-02
- 以相对方式操纵LocalDate属性
//以相对方式操作LocalDate
LocalDate date5 = LocalDate.of(2000, 1, 23);
//向后一周
LocalDate date6 = date5.plusWeeks(1);
//向前6年
LocalDate date7 = date6.minusYears(6);
//向后6个月
LocalDate date8 = date7.plus(6, ChronoUnit.MONTHS);
System.out.println(date8);//1994-07-30
- 使用 TemporalAdjuster来更加灵活的处理日期
//使用预定义的 TemporalAdjuster
LocalDate date9 = LocalDate.of(2000, 1, 1);
//下一个周末
LocalDate date10 = date9.with(nextOrSame(DayOfWeek.SUNDAY));
//当月最后一天
LocalDate date11 = date2.with(lastDayOfMonth());
TemporalAdjuster类中的工厂方法:
4. 打印输出及解析日期-时间对象
//按照某个模式创建 DateTimeFormatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date1 = LocalDate.of(2014, 3, 18);
//使用该模式将日期转换为字符串
String formattedDate = date1.format(formatter);
//使用parse方法解析字符串为日期
LocalDate date2 = LocalDate.parse(formattedDate, formatter);
System.out.println(formattedDate);
System.out.println(date2);
//格式不匹配会报错
System.out.println(LocalDate.parse("20/3/2000",formatter));
18/03/2014
2014-03-18
三、为日期添加时区
时区的处理是新版日期和时间 API 新增加的重要功能,使用新版日期和时间 API 时区的处理被极大地简化了。
ZoneId romeZone = ZoneId.of("Europe/Rome");
LocalDate date = LocalDate.of(2014, Month.MARCH, 18);
//以此时区和时间创建
ZonedDateTime zdt1 = date.atStartOfDay(romeZone);
LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45);
//以给定时间日期和时区信息创建
ZonedDateTime zdt2 = dateTime.atZone(romeZone);
//通过Instant和时区创建
Instant instant = Instant.now();
ZonedDateTime zdt3 = instant.atZone(romeZone);
System.out.println(zdt1);
System.out.println(zdt2);
System.out.println(zdt3);
System.out.println(new Date());
2014-03-18T00:00+01:00[Europe/Rome]
2014-03-18T13:45+01:00[Europe/Rome]
2021-07-02T10:38:27.194242100+02:00[Europe/Rome]
Fri Jul 02 16:38:27 CST 2021
总结
日期-时间-时区的关系可以大致如下
这次的时间日期学习让我想起了以前使用C++来处理时间的恐惧,只能说Java真香。学会了不同时间类型的创建、操纵、解析、输出和使用。