Date类

说Java 8中新的时间类之前,咱们先来说说Date类

  • 构造对象:平时构造Date类对象时,一般都会调用它的无参构造器,比如:获取当前时间作为创建时间Date createTime = new Date();
  • 源码分析:它的源码非常简洁,就是获取系统当前的时间戳(毫秒),赋值到内部变量fastTime中,并且提供了一个setTime方法来修改(非线程安全)
  1. public Date() {
  2. this(System.currentTimeMillis());
  3. }
  4. public Date(long date) {
  5. fastTime = date;
  6. }
  7. public void setTime(long time) {
  8. fastTime = time;
  9. cdate = null;
  10. }
  • 格式化时间:Date类默认提供的时间格式很难让人阅读,为了返回大家熟悉的时间格式(如”2021-07-21 12:00:00”),就需要通过SimpleDateFormat类(非线程安全)来协助格式化时间
  • 时间参照:有时,我们又需要以某个时间为准,获取它之前的n天,或者它之后的n天,就需要依赖Calendar类(非线程安全)
  1. // 构造一个新的Date类对象,并将它的引用赋值给对象变量createTime
  2. Date createTime = new Date();
  3. // 打印结果:1626851179912(毫秒时间戳)
  4. System.out.println(createTime.getTime());
  5. // 打印结果:Wed Jul 21 15:06:19 CST 2021(默认调用toString方法)
  6. System.out.println(createTime);
  7. // 使用SimpleDateFormat类来格式化时间
  8. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  9. // 打印结果:2021-07-21 15:06:19
  10. System.out.println(simpleDateFormat.format(createTime));
  11. // 获取当前时间30天之前
  12. Calendar calendar = Calendar.getInstance();
  13. calendar.setTime(createTime);
  14. calendar.add(Calendar.DATE, -30);
  15. Date beforeDay = calendar.getTime();
  16. System.out.println(simpleDateFormat.format(beforeDay));

可以看出,要想满足我们日常的时间处理,Date类需依赖其他类一起使用才能够满足,实现起来也略微繁琐;并且这些类都是非线程安全的(源码中的方法可以直接修改变量),在一些多线程的场景可能会出现超出预期的结果。

而Java 8中新的日期类就是为了解决这些问题:LocalDateLoccalTimeLocalDateTime

LocalDate

首先来说说LocalDate类,它主要存储的是时间的年、月、日

  • 构造对象:使用LocalDate类的静态方法:now或of
  • 源码分析:LocalDate是主要有三个变量year, month, day,它们都声明了final,一经赋值不再改变,因此Local类本身是不可变类;其次,它的许多操作数据的方法每次调用都会构建一个新的对象,如plusDays方法;并且,这个类是官方宣称的线程安全类(见类注释)
  1. /**
  2. * This class is immutable and thread-safe.
  3. * @since 1.8
  4. */
  5. public final class LocalDate
  6. implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable {
  7. ...
  8. private final int year;
  9. private final short month;
  10. private final short day;
  11. /**
  12. * 底层初始化数据方法,now和of方法最终都会调用这个私有的构造器,差别在于now获取的是当前系统的年月日,而of方法是校验当前输入的年月日
  13. */
  14. private LocalDate(int year, int month, int dayOfMonth) {
  15. this.year = year;
  16. this.month = (short) month;
  17. this.day = (short) dayOfMonth;
  18. }
  19. public LocalDate plusDays(long daysToAdd) {
  20. if (daysToAdd == 0) {
  21. return this;
  22. }
  23. long mjDay = Math.addExact(toEpochDay(), daysToAdd);
  24. return LocalDate.ofEpochDay(mjDay);
  25. }
  26. public static LocalDate ofEpochDay(long epochDay) {
  27. ...
  28. return new LocalDate(year, month, dom);
  29. }
  30. }
  • 格式化时间:LocalDate类默认的时间非常容易阅读(如2021-07-21),若需要做特殊格式(如2021年07月21日),就可以使用它内置的format方法,结合DateTimeFormatter类的ofPattern静态方法来实现
  • 时间参照:使用内置的plusDays就可以获取它之前的n天,或者它之后的n天
  1. LocalDate localDate1 = LocalDate.now();
  2. LocalDate localDate2 = LocalDate.of(2021, 7, 21);
  3. // 打印结果:2021-07-21
  4. System.out.println(localDate1);
  5. System.out.println(localDate2);
  6. // 使用本身的format方法结合DateTimeFormatter类的ofPattern方法来格式化时间
  7. // 打印结果:2021年07月21日
  8. System.out.println(localDate1.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
  9. // 获取当前时间30天之前,打印结果:2021-06-21
  10. System.out.println(localDate1.plusDays(30L));

LoccalTime

与LocalTime类区别在于,它存储的是小时、分钟、秒,其他如下:

  • 构造方法:同样使用静态方法now和of构造
  • 同样是不可变类,并且是线程安全
  • 格式化时间的方式也一样,只是可操作的只有时、分、秒
  • 获取相对时间方式,内置了plusHours,plusMinutes,plusSeconds等
  1. LocalTime localTime1 = LocalTime.now();
  2. LocalTime localTime2 = LocalTime.of(16, 49, 50);
  3. // 打印结果:16:50:50.328
  4. System.out.println(localTime1);
  5. // 打印结果:16:50:50
  6. System.out.println(localTime2);
  7. // 格式化后,打印结果:16时50分50秒
  8. System.out.println(localTime1.format(DateTimeFormatter.ofPattern("HH时mm分ss秒")));
  9. // 获取三小时后的时间,打印结果:19:50:50.328
  10. System.out.println(localTime1.plusHours(3L));

LocalDateTime

LocalDateTime类可以理解为是LocalDate和LocalTime的结合,存储年、月、日、小时、分、秒

  • 构造方法:同样使用静态方法now和of构造
  • 同样是不可变类,并且是线程安全
  • 格式化时间的方式也一样,不过操作范围更广了,是年、月、日、小时、分钟、秒
  • 获取相对时间方式更加丰富,内置了plusDays,plusHours,plusMinutes,plusSeconds等等
  1. LocalDateTime localDateTime1 = LocalDateTime.now();
  2. LocalDateTime localDateTime2 = LocalDateTime.of(2021, 7, 21, 17, 2, 50);
  3. // 打印结果:2021-07-21T17:02:50.614
  4. System.out.println(localDateTime1);
  5. // 打印结果:2021-07-21T17:02:50
  6. System.out.println(localDateTime2);
  7. // 格式化,打印结果:2021年07月21日 17时02分50秒
  8. System.out.println(localDateTime1.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒")));
  9. // 获取30天之前的时间,打印结果:2021-06-21T17:02:50.614
  10. System.out.println(localDateTime1.plusDays(-30L));

参考