为什么要引入新的日期时间类?
java.util.Date 缺陷:只能以毫秒表示时间,并且年份是从1900年开始,月份从0开始,易用性很差,很多方法已经废弃, 并且格式化DateFormat不是线程安全的,当多个线程同时使用同一个DateFormat会出现意想不到的错误
例如:表示2014.3.18
Date date = new Date(114, 2, 18);
它的打印输出效果为:
Tue Mar 18 00:00:00 CET 2014
java.util.Calendar 缺陷:只能以毫秒表示时间,月份从0开始
1. 主要类:
LocalDate:表示日期,只包含日期信息
LocalTime:表示时间,只包含时间信息,不包含日期
LocalDateTime:表示日期时间
ZoneId:表示时区
ZoneDateTime:表示带时区信息的日期时间
Instant:表示时刻,距离1970年1月1日午夜时分的秒数,是为了便于机器使用
Duration:表示时间间隔,时间差
屏幕快照 2019-12-30 下午11.59.19.png
2. 使用示例
public static void main(String[] args) {
//of(), now(), parse() 静态方法来实例化日期时间
LocalDate nowDate = LocalDate.now();
LocalDate date = LocalDate.of(2020,1,1);
System.out.println(nowDate);
LocalTime nowTime = LocalTime.now();
LocalTime time = LocalTime.of(12,0,0);
System.out.println(nowTime);
LocalDateTime nowDateTime = LocalDateTime.now();
LocalDateTime dateTime = LocalDateTime.of(date, time);
System.out.println(nowDateTime);
ZonedDateTime nowZonedDateTime = ZonedDateTime.now();
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zonedDateTime = ZonedDateTime.now(zoneId);
System.out.println(zonedDateTime);
//Date与LocalDateTime相互转换,由于LocalDateTime无时区信息,Date与时区有关,两者转换需要Instant + ZoneId协助
Date date1 = new Date();
LocalDateTime date2 = LocalDateTime.ofInstant(date1.toInstant(), ZoneId.systemDefault());
System.out.println("Date 转化成 LocalDateTime: " + date2);
LocalDateTime date3 = LocalDateTime.now();
Date date4 = Date.from(date3.atZone(ZoneId.systemDefault()).toInstant());
System.out.println("LocalDateTime 转化成 Date: " + date4);
//使用getXXX(),withXXX(),plusXXX(),minusXXX()等实例方法,来获取,修改,增加/减少某些域。
LocalDateTime date5 = LocalDateTime.now();
int year = date5.getYear();
int month = date5.getMonthValue();
int day = date5.getDayOfMonth();
int dayOfWeek = date5.getDayOfWeek().getValue();
date5 = date5.withYear(2019).withMonth(12).withDayOfMonth(31);
System.out.println(date5);
date5 = date5.plusYears(1).plusMonths(1).plusDays(1).plusSeconds(1).plusNanos(1);
System.out.println(date5);
//计算两个日期时间的差值,单位可精确到naos
Duration duration = Duration.between(nowDateTime, dateTime);
System.out.println("时间差:" + duration.toDays() + "天");
System.out.println("时间差:" + duration.toMinutes() + "分钟");
//格式化以及解析日期-时间对象
//java.time.format包提供了DateTimeFormatter格式化类,其中fomate()格式化日期,parse()解析日期方法
// 其中BASIC_ISO_DATE和ISO_LOCAL_DATE是DateTimeFormatter预定义实例
LocalDate date7 = LocalDate.of(2020, 1, 1);
String s1 = date7.format(DateTimeFormatter.BASIC_ISO_DATE); // 20200101
String s2 = date7.format(DateTimeFormatter.ISO_LOCAL_DATE); //2020-01-01
LocalDate date8 = LocalDate.parse("20200101", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date9 = LocalDate.parse("2020-01-01", DateTimeFormatter.ISO_LOCAL_DATE);
//自定义格式化类
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date10 = LocalDate.of(2020, 1, 1);
String formattedDate = date10.format(formatter); // 01/01/2020
LocalDate date11 = LocalDate.parse("01/01/2020", formatter);
}
3. 特性总结
- 以上时间日期类都是不可变类,都是不可修改的,对其日期时间的修改是通过创建副本完成
- 新的日期时间类可精确到纳秒,并且toString()打印出来更加易读