JDK8的新日期API

前言

Date、Calender 和SimpleDateFormat是我们在jdk8之前一直在使用的日期API,相信大家都使用的比较熟练了,也发现了它的使用中存在的一些问题。比如说,直接指定一个年月日通过Date类构造日期,打印后发现是错的日期,尤其是年很离谱,所以

    @Deprecated
    public Date(int year, int month, int date) {
        this(year, month, date, 0, 0, 0);
    }

这个方法也被标记为过期了。再则,使用Calender 使用它获得的月份是从0开始的,很不符合国人的习惯;还有SimpleDateFormat是线程不安全的,在多线程场景下,会解析错误或者直接抛异常了。
也是由于这些零碎的各种原因,jdk8推出了新的日期API.新的API单独放在了java.time包下。主要类有LocalDate、LocalTime、LocalDateTime,分别用来表示,日期(yyyy-MM-dd)、时间(HH:mm:ss)、日期时间(yyyy-MM-dd HH:mm:ss).接下里,我们具体看一下这些类的使用。

一、LocalDate

创建指定日期

     LocalDate date = LocalDate.of(2023, 5, 6); // 2022-05-06

就是这么简单,一个of搞定

得到当前日期

   LocalDate date = LocalDate.now(); //2023-09-20
   int year = date .getYear();     // 获取到年份
   Month month = date.getMonth();	// 获取到月份
   int dayOfMonth = date.getDayOfMonth(); 	// 获取到天
   DayOfWeek dayOfWeek = date2.getDayOfWeek();     // 获取到星期几

月份、和星期都是枚举,使用的时候,使用getValue()拿到值
有没有发现,System.out.println(date);打印的结果是直接格式化好的,简直太舒服了

二、LocalTime

创建指定的时间

   LocalTime time = LocalTime.of(5, 26, 33, 23145); //05:26:33.000023145

获取当前的时间

   LocalTime now = LocalTime.now(); // 15:07:08.959

   int hour = now.getHour(); // 获取小时
   int minute = now.getMinute(); // 获取分钟
   int second = now.getSecond(); // 获取秒
   int nano = now.getNano(); // 获取纳秒

三、LocalDateTime

创建指定的日期时间

    LocalDateTime dateTime = LocalDateTime.of(2028, 6, 1, 12, 12, 33, 1111); // 2023-09-20T15:11:23.656

获取当前日期时间

 LocalDateTime now = LocalDateTime.now();

 int year = now.getYear(); // 获取年份
 Month month = now.getMonth(); // 获取月份
 int dayOfMonth = now.getDayOfMonth(); // 获取日
 DayOfWeek dayOfWeek = now.getDayOfWeek(); // 获取第几周
 int hour = now.getHour(); // 获取小时
 int minute = now.getMinute(); // 获取分钟
 int second = now.getSecond(); // 获取秒
 int nano = now.getNano(); // 获取纳秒

日期时间的修改和和比较

        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);

        // 修改日期时间  对日期时间的修改,对于已存在的LocalDateTime,创建了它的模版,
        // 不会修改原来创建的日期时间,会新创建一个LocalDateTime 对象
        LocalDateTime localDateTime = now.withYear(1998); // 直接将当前年份修改为1998年
        System.out.println(now);
        System.out.println(localDateTime);

        // 直接修改到指定的时间
        System.out.println(now.withMonth(10)); // 直接将当前年份改为10月份
        System.out.println(now.withDayOfMonth(6)); // 直接将当前日改为6日
        System.out.println(now.withMinute(15));  // 直接将分钟改为15分钟

        // 对当前日期时间的基础上,加上或者减去指定的时间
        System.out.println(now.plusDays(2));  // 加两天   ,两天后
        System.out.println(now.plusYears(10)); // 加10年 ,十年后
        System.out.println(now.plusMonths(6)); // 加6个月 ,6个月后

        System.out.println(now.minusYears(10)); // 减去10年 10年前

        System.out.println(now.minusMonths(6)); // 减去6个月 半年前

        System.out.println(now.minusDays(7)); // 减去7天 一周前

有没有发现,日期时间的加减变的非常的方便,直接有对应的方法进行操作,不用在使用Calender 类进行操作了。

日期时间的比较

        LocalDate now = LocalDate.now();
        LocalDate date = LocalDate.of(2020, 1, 1);
        // 在Jdk8中实现日期的比较 now.isAfter(date)
        System.out.println(now.isAfter(date));  // now 在date之后吗 在返回true,不在返回false
        System.out.println(now.isBefore(date));  // now在date之前吗? 在返回true ,不在返回false
        System.out.println(now.isEqual(date)); // now和date相等吗

日期的比较也变得相当简单,也有对应的方法,主要是要弄明白方法的含义,例如:a.isAfter(b) 表示a日期是在b日期的后边吗?

日期的格式化和解析操作

        LocalDateTime now = LocalDateTime.now();

        // 指定格式 使用系统默认的格式
        DateTimeFormatter isoLocalDateTime = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        // 将日期时间转换成字符串
        String format = now.format(isoLocalDateTime);
        System.out.println(format); // 2023-09-19T10:50:44.171

        //  通过ofPattern 方法来指定特定的格式
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format1 = now.format(dateTimeFormatter); // 2023-09-20 15:23:39
        System.out.println(format1);

        // 将字符串解析为一个日期时间类
        LocalDateTime parse = LocalDateTime.parse("2023-09-19 16:22:56", dateTimeFormatter);
        System.out.println(parse); // 2023-09-19T16:22:56

四、一些常用类的介绍

Instant 类

在jdk8中新增的一个时间戳/时间线,内部保存了从1970年1月1日 00:00:00以来的秒和纳秒

       Instant now = Instant.now();
       System.out.println(now); // 2023-09-20T07:27:20.103Z 

       // 获取从1970年一月一日 00:00:00 到现在的纳秒
       System.out.println(now.getNano()); // 103000000
       Thread.sleep(5); // 5毫秒
       Instant now1 = Instant.now();
       System.out.println(now1.getNano() - now.getNano()); //39000000

Instant now = Instant.now();也可以获取到当前的日期时间,但是它没有获取年、月、日、时分秒的方法。只能获取到纳秒或秒

Duration 和 Period两个工具类

用来计算日期时间的差
Duration: 用来计算两个时间差(LocalTIme)
Period: 用来计算两个日期差(LocalDate)

计算两个时间差

        LocalTime now = LocalTime.now();
        LocalTime time = LocalTime.of(22, 48, 59);
        System.out.println(now); //11:15:22.162
        Duration duration = Duration.between(now, time);
        System.out.println(duration.toDays());  // 获取相差的天数
        System.out.println(duration.toHours()); // 获取相差的小时
        System.out.println(duration.toMinutes()); // 获取相差的分钟
        System.out.println(duration.toMillis()); // 获取相差的毫秒

计算两个日期差

        LocalDate nowDate = LocalDate.now();
        System.out.println(nowDate); // 2023-09-19
        LocalDate date = LocalDate.of(1997, 12, 5);

        Period period = Period.between(date, nowDate);

        System.out.println(period.getYears()); // 25
        System.out.println(period.getMonths()); // 9 为什么是9呢,因为Period.between(date, nowDate);方法是通过后边的(nowDate)减去前边的(date),这样nowDate时间大,在后边,1997在前边,9月往前数到前一年的12月,刚好是差9个月
        System.out.println(period.getDays()); // 14

TemporalAdjuster 和 TemporalAdjusters

  TemporalAdjuster: 时间矫正器
  TemporalAdjusters :通过该类的静态方法提供了大量的常用的TemporalAdjuster实现。

有时候我们可能需要如下调整: 将日期调整到“下个月的第一天”等操作。这时我们通过时间矫正器效果可能会更好。

通过TemporalAdjuster实现

        LocalDateTime now = LocalDateTime.now();
        // 将当期的日期调整到下个月的一号
        TemporalAdjuster adjuster = (temporal) -> {
            LocalDateTime dateTime = (LocalDateTime) temporal;
            LocalDateTime nextMonth = dateTime.plusMonths(1).withDayOfMonth(1);
            return nextMonth;
        };
        LocalDateTime nextMonth = now.with(adjuster);
        System.out.println(nextMonth);

通过TemporalAdjusters 实现

        LocalDateTime nextMonth = now.with(TemporalAdjusters.firstDayOfNextMonth());
        System.out.println(nextMonth);

TemporalAdjusters 还有很多静态方法,用到的时候,大家自行选择就好。

五、日期时间的时区

  1、ava8加入了对时区的支持,LocalDate、LocalTime、LocalDateTime是不带时区的,带时区的日期时间类分别为:
  ZoneDate、ZoneTime、ZoneDateTime
  2、其中每个时区都对应着ID,ID的格式为“区域/城市”。例如:Asia/Shanghai等。
  3、ZoneId:该类中包含了所有时区信息。
        //  时区操作
        //  1、获取所有的时区id
        ZoneId.getAvailableZoneIds().forEach(System.out::println);
        //     获取当前时间 中国使用的 是东八区的时区,比标准时间晚8个小时
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);// 2023-09-19T15:52:27.673

        // 获取标准时间
        ZonedDateTime bz = ZonedDateTime.now(Clock.systemUTC());
        System.out.println(bz);//2023-09-19T07:52:27.673Z

        // 使用计算机默认的时区,创建日期时间
        ZonedDateTime now1 = ZonedDateTime.now();
        System.out.println(now1); //2023-09-19T15:52:27.673+08:00[Asia/Shanghai]

        // 使用指定的时区创建日期时间
        ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of("America/Marigot"));
        System.out.println(now2);

由于在国内,计算机默认时区则是东八区(Asia/Shanghai)所以,我们平时开发,不用关注时区的事情,当在国际化项目开中则需要留意时区的问题。

小结

如果能读到这里,也会有一个直观的感受,新的日期API规律性很强,见文知意,不用特意记忆,读一遍后也能了解个大概,也知道获取个当前的日期时间,该怎么做了,这个便是API的魅力所在。
回顾下常用API:

LocalDate now = LocalDate.now();
LocalTime now = LocalTime.now();
LocalDateTime now = LocalDateTime.now();

在加一个日期时间格式化器,就基本够用了

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);
String format = now.format(dateTimeFormatter);

你可能感兴趣的:(java基础,java)