java 8 新特性 日期和时间类操作案例

java 8 新特性 日期和时间类操作案例

LocalDate、LocalTime、LocalDateTime类的实例是不可变的对象,分别表示使用 ISO-8601 日历系统的日期、时 间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。

// LocalDate:获取日期时间的信息。格式为 2019-10-16
@Test
public void test01() {
        // 创建指定日期
        LocalDate fj = LocalDate.of(1985, 9, 23);
        System.out.println("fj = " + fj); // 1985-09-23
        // 得到当前日期
        LocalDate nowDate = LocalDate.now();
        System.out.println("nowDate = " + nowDate); // 2019-10-16
        // 获取日期信息
        System.out.println("年: " + nowDate.getYear());
        System.out.println("月: " + nowDate.getMonthValue());
        System.out.println("日: " + nowDate.getDayOfMonth());
        System.out.println("星期: " + nowDate.getDayOfWeek());
    }

// LocalTime类: 获取时间信息。格式为 16:38:54.158549300
@Test
 public void test02() {
        // 得到指定的时间
        LocalTime time = LocalTime.of(12,15, 28, 129_900_000);
        System.out.println("time = " + time);
        // 得到当前时间
        LocalTime nowTime = LocalTime.now();
        System.out.println("nowTime = " + nowTime);
        // 获取时间信息
        System.out.println("小时: " + nowTime.getHour());
        System.out.println("分钟: " + nowTime.getMinute());
        System.out.println("秒: " + nowTime.getSecond());
        System.out.println("纳秒: " + nowTime.getNano());
    }

// LocalDateTime类: 获取日期时间信息。格式为 2018-09-06T15:33:56.750
@Test
public void test03() {
    LocalDateTime fj = LocalDateTime.of(1985, 9, 23, 9, 10, 20);
    System.out.println("fj = " + fj); // 1985-09-23T09:10:20
    // 得到当前日期时间
    LocalDateTime now = LocalDateTime.now();
    System.out.println("now = " + now); // 2019-10-16T16:42:24.497896800
    System.out.println(now.getYear());
    System.out.println(now.getMonthValue());
    System.out.println(now.getDayOfMonth());
    
    System.out.println(now.getHour());
    System.out.println(now.getMinute());
    System.out.println(now.getSecond());
    System.out.println(now.getNano());
}

对日期时间的修改,对已存在的LocalDate对象,创建它的修改版,最简单的方式是使用withAttribute方法。 withAttribute方法会创建对象的一个副本,并按照需要修改它的属性。以下所有的方法都返回了一个修改属性的对 象,他们不会影响原来的对象。

// LocalDateTime类: 对日期时间的修改
@Test
public void test05() {
    LocalDateTime now = LocalDateTime.now();
    System.out.println("now = " + now);
    
    // 修改日期时间
    LocalDateTime setYear = now.withYear(2078);
    System.out.println("修改年份: " + setYear);
    System.out.println("now == setYear: " + (now == setYear));
    System.out.println("修改月份: " + now.withMonth(6));
    System.out.println("修改小时: " + now.withHour(9));
    System.out.println("修改分钟: " + now.withMinute(11));
    
    // 再当前对象的基础上加上或减去指定的时间
    LocalDateTime localDateTime = now.plusDays(5);
    System.out.println("5天后: " + localDateTime);
    System.out.println("now == localDateTime: " + (now == localDateTime));
    System.out.println("10年后: " + now.plusYears(10));
    System.out.println("20月后: " + now.plusMonths(20));
    System.out.println("20年前: " + now.minusYears(20));
    System.out.println("5月前: " + now.minusMonths(5));
    System.out.println("100天前: " + now.minusDays(100));
}

日期时间的比较

// 日期时间的比较
@Test
public void test06() {
    // 在JDK8中,LocalDate类中使用isBefore()、isAfter()、equals()方法来比较两个日期,可直接进行比较。
    LocalDate now = LocalDate.now();
    LocalDate date = LocalDate.of(2018, 8, 8);
    System.out.println(now.isBefore(date)); // false
    System.out.println(now.isAfter(date)); // true
}

时间格式化与解析

通过 java.time.format.DateTimeFormatter 类可以进行日期时间解析与格式化。

// 日期格式化
@Test
public void test04() {
    // 得到当前日期时间
    LocalDateTime now = LocalDateTime.now();
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    // 将日期时间格式化为字符串
    String format = now.format(formatter);
    System.out.println("format = " + format);
    
    // 将字符串解析为日期时间
    LocalDateTime parse = LocalDateTime.parse("1985-09-23 10:12:22", formatter);
    System.out.println("parse = " + parse);
}

Instant 类

Instant 时间戳/时间线,内部保存了从1970年1月1日 00:00:00以来的秒和纳秒。

// 时间戳
@Test
public void test07() {
    Instant now = Instant.now();
    System.out.println("当前时间戳 = " + now);
    
    // 获取从1970年1月1日 00:00:00的秒
    System.out.println(now.getNano());
    System.out.println(now.getEpochSecond());
    System.out.println(now.toEpochMilli());
    System.out.println(System.currentTimeMillis());
    
    Instant instant = Instant.ofEpochSecond(5);
    System.out.println(instant);
}

计算日期时间差类

Duration/Period类: 计算日期时间差。

  1. Duration:用于计算2个时间(LocalTime,时分秒)的距离
  2. Period:用于计算2个日期(LocalDate,年月日)的距离
// Duration/Period类: 计算日期时间差
@Test
public void test08() {
    
    // Duration计算时间的距离
    LocalTime now = LocalTime.now();
    LocalTime time = LocalTime.of(14, 15, 20);
    Duration duration = Duration.between(time, now);
    System.out.println("相差的天数:" + duration.toDays());
    System.out.println("相差的小时数:" + duration.toHours());
    System.out.println("相差的分钟数:" + duration.toMinutes());
    System.out.println("相差的秒数:" + duration.toSeconds());
    
    // Period计算日期的距离
    LocalDate nowDate = LocalDate.now();
    LocalDate date = LocalDate.of(1998, 8, 8);
    
    // 让后面的时间减去前面的时间
    Period period = Period.between(date, nowDate);
    System.out.println("相差的年:" + period.getYears());
    System.out.println("相差的月:" + period.getMonths());
    System.out.println("相差的天:" + period.getDays());
}

的时间校正器

有时我们可能需要获取例如:将日期调整到“下一个月的第一天”等操作。可以通过时间校正器来进行。

  1. TemporalAdjuster : 时间校正器。
  2. TemporalAdjusters : 该类通过静态方法提供了大量的常用TemporalAdjuster的实现。
// TemporalAdjuster类:自定义调整时间
@Test
public void test09() {
    LocalDateTime now = LocalDateTime.now();
    // 得到下一个月的第一天
    TemporalAdjuster firsWeekDayOfNextMonth = temporal -> {
            LocalDateTime dateTime = (LocalDateTime) temporal;
            LocalDateTime nextMonth = dateTime.plusMonths(1).withDayOfMonth(1);
            System.out.println("nextMonth = " + nextMonth);
         return nextMonth;
    };
    
    LocalDateTime nextMonth = now.with(firsWeekDayOfNextMonth);
    System.out.println("nextMonth = " + nextMonth);
}

设置日期时间的时区

Java8 中加入了对时区的支持,LocalDate、LocalTime、LocalDateTime是不带时区的,带时区的日期时间类分别 为:ZonedDate、ZonedTime、ZonedDateTime。

其中每个时区都对应着 ID,ID的格式为 “区域/城市” 。例如 :Asia/Shanghai 等。

ZoneId:该类中包含了所有的时区信息。

// 设置日期时间的时区
@Test
public void test10() {
    // 1.获取所有的时区ID
    // ZoneId.getAvailableZoneIds().forEach(System.out::println);
    // 不带时间,获取计算机的当前时间
    LocalDateTime now = LocalDateTime.now(); // 中国使用的东八区的时区.比标准时间早8个小时
    System.out.println("now = " + now);
    
    // 2.操作带时区的类
    // now(Clock.systemUTC()): 创建世界标准时间
    ZonedDateTime bz = ZonedDateTime.now(Clock.systemUTC());
    System.out.println("bz = " + bz);
    
    // now(): 使用计算机的默认的时区,创建日期时间
    ZonedDateTime now1 = ZonedDateTime.now();
    System.out.println("now1 = " + now1); // 2019-10-
    19T16:19:44.007153500+08:00[Asia/Shanghai]
    
    // 使用指定的时区创建日期时间
    ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of("America/Vancouver"));
    System.out.println("now2 = " + now2); // 2019-10-19T01:21:44.248794200-
    07:00[America/Vancouver]
}

小结

详细学习了新的日期是时间相关类,LocalDate表示日期,包含年月日,LocalTime表示时间,包含时分 秒,LocalDateTime = LocalDate + LocalTime,时间的格式化和解析,通过DateTimeFormatter类型进行.

学习了Instant类,方便操作秒和纳秒,一般是给程序使用的.学习Duration/Period计算日期或时间的距离,还使用时间调 整器方便的调整时间,学习了带时区的3个类ZoneDate/ZoneTime/ZoneDateTime

JDK 8新的日期和时间 API的优势:

  1. 新版的日期和时间API中,日期和时间对象是不可变的。操纵的日期不会影响老值,而是新生成一个实例。
  2. 新的API提供了两种不同的时间表示方式,有效地区分了人和机器的不同需求。
  3. TemporalAdjuster可以更精确的操纵日期,还可以自定义日期调整器。
  4. 是线程安全的

发布于 2021-12-02 21:43