为什么JDK8要新增日期类

/**
 *  目标:搞清楚为什么要用JDK 8开始新增的时间类。
 */
public class Test {
    public static void main(String[] args) {
        // 传统的时间类(Date、SimpleDateFormat、Calendar)存在如下问题:
        // 1、设计不合理,使用不方便,很多都被淘汰了。
        Date d = new Date();
        System.out.println(d.getYear()); // 获取的是125, 而不是现在的2025年
        System.out.println(d.getYear() + 1900);
​
        // Calendar也不是很合理, 因为需要去记住日历的每个字段信息
        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        System.out.println(year);
​
        /**
         * 2、都是可变对象,修改后会丢失最开始的时间信息。
         * 比如:
         *      Calendar.set()方法, 重新设置后当前的日期就获取不到了
         *      Date.setTime(time)方法, 重新设置后之前的信息就获取不到了
         */
​
        /**
         * 3、线程不安全。(后边知识会学习)
         * 了解下: 比如有很多用户会一起用时间对象, 如果其中一个人把时间修改了,
         *      另一个人也把时间进行了修改, 最终获取的时间是以哪个人为主, 就会产生冲突.
         */
​
        /**
         * 4、不能精确到纳秒,只能精确到毫秒。
         *    1秒 = 1000毫秒
         *    1毫秒 = 1000微妙
         *    1微妙 = 1000纳秒
         */
    }
}

JDK8日期、时间、日期时间

        接下来,我们学习一下JDK8新增的日期类。为什么以前的Date类就可以表示日期,为什么要有新增的日期类呢?原因如下

DK8新增的日期类分得更细致一些,比如表示年月日用LocalDate类、表示时分秒用LocalTime类、而表示年月日时分秒用LocalDateTime类等;除了这些类还提供了对时区、时间间隔进行操作的类等。它们几乎把对日期/时间的所有操作都通过了API方法,用起来特别方便。

先学习表示日期、时间、日期时间的类;有LocalDate、LocalTime、以及LocalDateTime类。仔细阅读代码,你会发现这三个类的用法套路都是一样的。

LocalDate:代表本地日期(年、月、日、星期)
LocalTime:代表本地时间(时、分、秒、纳秒)
LocalDateTime:代表本地日期、时间(年、月、日、星期、时、分、秒、纳秒)

它们获取对象的方案

方法名实例
public static Xxxx now(): 获取系统当前时间对应的该对象LocaDate ld = LocalDate.now(); LocalTime lt = LocalTime.now(); LocalDateTime ldt = LocalDateTime.now();
public static Xxxx of(…):获取指定时间的对象LocalDate localDate1 = LocalDate.of(2099 , 11,11); LocalTime localTime1 = LocalTime.of(9, 8, 59); LocalDateTime localDateTime1 = LocalDateTime.of(2025, 11, 16, 14, 30, 01);
  • LocalDate类的基本使用

LocalDate的常用API(都是处理年、月、日、星期相关的)。

方法名说明
public int getYear()获取年
public int getMonthValue()获取月份(1-12)
public int getDayOfMonth()获取日
public int getDayOfYear()获取当前是一年中的第几天
Public DayOfWeek getDayOfWeek()获取星期几:ld.getDayOfWeek().getValue()
withYear、withMonth、withDayOfMonth、withDayOfYear直接修改某个信息,返回新日期对象
plusYears、plusMonths、plusDays、plusWeeks把某个信息加多少,返回新日期对象
minusYears、minusMonths、minusDays,minusWeeks把某个信息减多少,返回新日期对象
equals isBefore isAfter判断两个日期对象,是否相等,在前还是在后

下面看代码,演示一下

public class LocalDateTest {
    public static void main(String[] args) {
        // 0、获取本地日期对象(不可变对象)
        LocalDate ld = LocalDate.now(); // 年 月 日
        System.out.println(ld);
​
        System.out.println("----------------------");
​
        // 1、获取日期对象中的信息
        int year = ld.getYear(); // 年
        int month = ld.getMonthValue(); // 月(1-12)
        int day = ld.getDayOfMonth(); // 日
        int dayOfYear = ld.getDayOfYear();  // 一年中的第几天
        int dayOfWeek = ld.getDayOfWeek().getValue(); // 星期几
        System.out.println(year);
        System.out.println(month);
        System.out.println(day);
        System.out.println(dayOfYear);
        System.out.println(dayOfWeek);
​
        System.out.println("----------------------");
​
        // 2、直接修改某个信息: withYear、withMonth、withDayOfMonth、withDayOfYear
        LocalDate ld2 = ld.withYear(2099); // 修改年
        System.out.println(ld2);
        LocalDate ld3 = ld.withMonth(12); // 修改月
        System.out.println(ld3);
        System.out.println(ld); // 原始时间不会发生改变
​
        System.out.println("----------------------");
​
        // 3、把某个信息加多少: plusYears、plusMonths、plusDays、plusWeeks
        LocalDate ld4 = ld.plusYears(2);
        System.out.println(ld4);
        LocalDate ld5 = ld.plusMonths(2);
        System.out.println(ld5);
​
        System.out.println("----------------------");
​
        // 4、把某个信息减多少:minusYears、minusMonths、minusDays、minusWeeks
        LocalDate ld6 = ld.minusYears(2);
        System.out.println(ld6);
        LocalDate ld7 = ld.minusMonths(2);
        System.out.println(ld7);
​
        System.out.println("----------------------");
​
        // 5、获取指定日期的LocalDate对象: public static LocalDate of(int year, int month, int dayOfMonth)
        LocalDate ld8 = LocalDate.of(2099, 12, 12);
        System.out.println(ld8);
        LocalDate ld9 = LocalDate.of(2099, 12, 12);
        System.out.println(ld9);
​
        // 6、判断2个日期对象,是否相等,在前还是在后: equals isBefore isAfter
        System.out.println(ld8.equals(ld9)); // 日期是否相等 true
        System.out.println(ld8.isAfter(ld)); // 当前时间是否在ld之后 true
        System.out.println(ld8.isBefore(ld)); // 当前时间是否在ld之前 false
    }
}

LocalDateTime的常用API(可以处理年、月、日、星期、时、分、秒、纳秒等信息)

方法名说明
getYear、getMonthValue、getDayOfMonth、getDayOfYear、getDayOfWeek、getHour、getMinute、getSecond、getNano获取年月日、时分秒、纳秒等
withYear、withMonth、withDayOfMonth、withDayOfYear、withHour、withMinute、withSecond、withNano修改某个信息,返回新日期时间对象
plusYears、plusMonths、plusDays、plusWeeks、plusHours、plusMinutes、plusSeconds、plusNanos把某个信息加多少,返回新日期时间对象
minusYears、minusMonths、minusDays、minusWeeks、minusHours、minusMinutes、minusSeconds、minusNanos把某个信息减多少,返回新日期时间对象
equals isBefore isAfter判断2个时间对象,是否相等,在前还是在后

下面看代码,演示一下

public class LocalDateTimeTest {
    public static void main(String[] args) {
        // 0、获取本地日期和时间对象。
        LocalDateTime ldt = LocalDateTime.now(); // 年 月 日 时 分 秒 纳秒
        System.out.println(ldt);
​
        // 1、可以获取日期和时间的全部信息
        int year = ldt.getYear(); // 年
        int month = ldt.getMonthValue(); // 月
        int day = ldt.getDayOfMonth(); // 日
        int dayOfYear = ldt.getDayOfYear();  // 一年中的第几天
        int dayOfWeek = ldt.getDayOfWeek().getValue();  // 获取是周几
        int hour = ldt.getHour(); //时
        int minute = ldt.getMinute(); //分
        int second = ldt.getSecond(); //秒
        int nano = ldt.getNano(); //纳秒
​
        // 2、修改时间信息:
        // withYear withMonth withDayOfMonth withDayOfYear withHour
        // withMinute withSecond withNano
        LocalDateTime ldt2 = ldt.withYear(2029);
        LocalDateTime ldt3 = ldt.withMinute(59);
​
        // 3、加多少:
        // plusYears  plusMonths plusDays plusWeeks plusHours plusMinutes plusSeconds plusNanos
        LocalDateTime ldt4 = ldt.plusYears(2);
        LocalDateTime ldt5 = ldt.plusMinutes(3);
​
        // 4、减多少:
        // minusDays minusYears minusMonths minusWeeks minusHours minusMinutes minusSeconds minusNanos
        LocalDateTime ldt6 = ldt.minusYears(2);
        LocalDateTime ldt7 = ldt.minusMinutes(3);
​
​
        // 5、获取指定日期和时间的LocalDateTime对象:
        // public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour,
        //                                  int minute, int second, int nanoOfSecond)
        LocalDateTime ldt8 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);
        LocalDateTime ldt9 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);
​
        // 6、 判断2个日期、时间对象,是否相等,在前还是在后: equals、isBefore、isAfter
        System.out.println(ldt9.equals(ldt8));
        System.out.println(ldt9.isAfter(ldt));
        System.out.println(ldt9.isBefore(ldt));
​
        System.out.println("--------------------------");
​
        // 7、可以把LocalDateTime转换成LocalDate和LocalTime
        // public LocalDate toLocalDate()
        // public LocalTime toLocalTime()
        // public static LocalDateTime of(LocalDate date, LocalTime time)
        LocalDate ld = ldt.toLocalDate();
        System.out.println(ld);
        LocalTime lt = ldt.toLocalTime();
        System.out.println(lt);
        // 合并LocalDateTime对象
        LocalDateTime ldt10 = LocalDateTime.of(ld, lt);
        System.out.println(ldt10);
    }
}

  • LocalTime类的基本使用

  • LocalTime的常用API(都是处理时、分、秒、纳秒相关的)。

    方法名说明
    public int getHour()获取小时
    public int getMinute()获取分
    public int getSecond()获取秒
    public int getNano()获取纳秒
    withHour、withMinute、withSecond、withNano修改时间,返回新时间对象
    plusHours、plusMinutes、plusSeconds、plusNanos把某个信息加多少,返回新时间对象
    minusHours、minusMinutes、minusSeconds、minusNanos把某个信息减多少,返回新时间对象
    equals isBefore isAfter判断2个时间对象,是否相等,在前还是在后

    下面看代码,演示一下

    public class LocalTimeTest {
        public static void main(String[] args) {
            // 0、获取本地时间对象
            LocalTime lt = LocalTime.now(); // 时 分 秒 纳秒 不可变的
            System.out.println(lt);
    ​
            // 1、获取时间中的信息
            int hour = lt.getHour(); //时
            int minute = lt.getMinute(); //分
            int second = lt.getSecond(); //秒
            int nano = lt.getNano(); //纳秒
    ​
            // 2、修改时间:withHour、withMinute、withSecond、withNano
            LocalTime lt3 = lt.withHour(10);
            LocalTime lt4 = lt.withMinute(10);
            LocalTime lt5 = lt.withSecond(10);
            LocalTime lt6 = lt.withNano(10);
    ​
            // 3、加多少:plusHours、plusMinutes、plusSeconds、plusNanos
            LocalTime lt7 = lt.plusHours(10);
            LocalTime lt8 = lt.plusMinutes(10);
            LocalTime lt9 = lt.plusSeconds(10);
            LocalTime lt10 = lt.plusNanos(10);
    ​
            // 4、减多少:minusHours、minusMinutes、minusSeconds、minusNanos
            LocalTime lt11 = lt.minusHours(10);
            LocalTime lt12 = lt.minusMinutes(10);
            LocalTime lt13 = lt.minusSeconds(10);
            LocalTime lt14 = lt.minusNanos(10);
    ​
            // 5、获取指定时间的LocalTime对象:
            // public static LocalTime of(int hour, int minute, int second)
            LocalTime lt15 = LocalTime.of(12, 12, 12);
            LocalTime lt16 = LocalTime.of(12, 12, 12);
    ​
            // 6、判断2个时间对象,是否相等,在前还是在后: equals isBefore isAfter
            System.out.println(lt15.equals(lt16)); // true
            System.out.println(lt15.isAfter(lt)); // false
            System.out.println(lt15.isBefore(lt)); // true
        }
    }
  • LocalDateTime类的基本使用

JDK8日期(时区)

接着,我们学习代表时区的两个类。

什么是时区?

由于世界各个国家与地区的经度不同,各地区的时间也有所不同,因此会划分为24个不同的时区。每一个时区的时间也不太一样。

世界标准时间: UTC

中国标准时间: 世界标准时间(UTC) + 8小时

ZoneId 时区的常见方法

方法名说明
public static Set<String> getAvailableZoneIds()获取Java中支持的所有时区
public static ZoneId systemDefault()获取系统默认时区
public static ZoneId of(String zoneId)获取一个指定时区

ZonedDateTime 带时区时间的常见方法

方法名说明
public static ZonedDateTime now()获取当前时区的ZonedDateTime对象
public static ZonedDateTime now(ZoneId zone)获取指定时区的ZonedDateTime对象
getYear、getMonthValue、getDayOfMonth、getDayOfYeargetDayOfWeek、getHour、getMinute、getSecond、getNano获取年月日、时分秒、纳秒等
public ZonedDateTime withXxx(时间)修改时间系列的方法
public ZonedDateTime minusXxx(时间)减少时间系列的方法
public ZonedDateTime plusXxx(时间)增加时间系列的方法

下面看代码,演示一下

public class ZoneId_ZonedDateTime {
    public static void main(String[] args) {
        // 目标:了解时区和带时区的时间。
        // 1、ZoneId的常见方法:
        // public static ZoneId systemDefault(): 获取系统默认的时区
        ZoneId zoneId = ZoneId.systemDefault();
        System.out.println(zoneId.getId());
        System.out.println(zoneId); //zoneId输出时实际调用的是toString()方法
​
        System.out.println("-----------------------");
​
        // public static Set<String> getAvailableZoneIds(): 获取Java支持的全部时区Id
        System.out.println(ZoneId.getAvailableZoneIds());
​
        System.out.println("-----------------------");
​
        // public static ZoneId of(String zoneId) : 把某个时区id封装成ZoneId对象。
        ZoneId zoneId1 = ZoneId.of("America/New_York");
        System.out.println(zoneId1);
​
        System.out.println("========================");
​
        // 2、ZonedDateTime:带时区的时间。
        // public static ZonedDateTime now(ZoneId zone): 获取某个时区的ZonedDateTime对象。
        ZonedDateTime now = ZonedDateTime.now(zoneId1);
        System.out.println(now);
​
        // 世界标准时间了
        ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());
        System.out.println(now1);
​
        // public static ZonedDateTime now():获取系统默认时区的ZonedDateTime对象
        ZonedDateTime now2 = ZonedDateTime.now();
        System.out.println(now2);
​
        // 扩展知识点: Calendar也可以获取时区信息
        Calendar instance = Calendar.getInstance(TimeZone.getTimeZone(zoneId1));
        System.out.println(instance);
    }
}

JDK8日期(Instant类)

接下来,我们来学习Instant这个类。通过获取Instant的对象可以拿到此刻的时间,该时间由两部分组成:从1970-01-01 00:00:00 开始走到此刻的总秒数 + 不够1秒的纳秒数。

该类提供的方法如下图所示,可以用来获取当前时间,也可以对时间进行加、减、获取等操作。

作用:可以用来记录代码的执行时间,或用于记录用户操作某个事件的时间点。

注意:
    传统的Date类,只能精确到毫秒,并且是可变对象;
    新增的Instant类,可以精确到纳秒,并且是不可变对象,推荐用Instant代替Date。

下面看代码,演示一下

/**
 * 目标:掌握Instant的使用。
 */
public class InstantTest {
    public static void main(String[] args) {
        // 1、创建Instant的对象,获取此刻时间信息
        Instant now = Instant.now(); // 不可变对象
​
        // 2、获取总秒数
        long second = now.getEpochSecond();
        System.out.println(second);
​
        // 3、不够1秒的纳秒数
        int nano = now.getNano();
        System.out.println(nano);
​
        System.out.println(now);
​
        // plus增加系列的方法
        Instant instant = now.plusNanos(111);
        System.out.println(instant);
​
        // Instant对象的作用:做代码的性能分析,或者记录用户的操作时间点
        Instant now1 = Instant.now();
        // 代码执行。。。。
        Instant now2 = Instant.now();
​
        /**
         * LocalDateTime也可以获取某个时刻/时间戳, 为什么要用Instant呢?
         * 因为LocalDateTime获取不到从1970-01-01 00:00:00 开始走到此刻的总秒数
         * 只能获取到纳秒数
         */
        LocalDateTime l = LocalDateTime.now();
        System.out.println(l);
    }
}

JDK8日期(格式化器)

接下来,我们学习一个新增的日期格式化类,叫DateTimeFormater。它可以从来对日期进行格式化和解析。它代替了原来的SimpleDateFormat类。

需要用到的方法,如下图所示

接下来,将上面的方法用代码来演示一下

/**
 *  目标:掌握JDK 8新增的DateTimeFormatter格式化器的用法。
 */
public class DateTimeFormatterTest {
    public static void main(String[] args) {
        // 1、创建一个日期时间格式化器对象出来。
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
​
        // 2、对时间进行格式化
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
​
        String rs = formatter.format(now); // 正向格式化
        System.out.println(rs);
​
        System.out.println("-----------------------------");
​
        // 3、格式化时间,其实还有一种方案。
        String rs2 = now.format(formatter); // 反向格式化
        System.out.println(rs2);
​
        // 4、解析时间:解析时间一般使用LocalDateTime提供的解析方法来解析。
        String dateStr = "2029年12月12日 12:12:11";
        LocalDateTime ldt = LocalDateTime.parse(dateStr, formatter);
        System.out.println(ldt);
    }
}

JDK8日期(Period类)

除以了上新增的类,JDK8还补充了两个类,一个叫Period类、一个叫Duration类;这两个类可以用来对计算两个时间点的时间间隔。(比如: 倒计时相关业务)

其中Period用来计算日期间隔(年、月、日),Duration用来计算时间间隔(时、分、秒、纳秒)先来演示Period类的用法,它的方法如下图所示。可以用来计算两个日期之间相隔的年、相隔的月、相隔的日。只能两个计算LocalDate对象之间的间隔

/**
 * 目标:掌握Period的作用:计算机两个日期相差的年数,月数、天数。
 */
public class PeriodTest {
    public static void main(String[] args) {
        LocalDate start = LocalDate.of(2029, 8, 10);
        LocalDate end = LocalDate.of(2029, 12, 15);
​
        // 1、创建Period对象,封装两个日期对象。
        Period period = Period.between(start, end);
​
        // 2、通过period对象获取两个日期对象相差的信息。
        System.out.println(period.getYears());
        System.out.println(period.getMonths());
        System.out.println(period.getDays());
    }
}

JDK8日期(Duration类)

接下来,我们学习Duration类。它是用来表示两个时间对象的时间间隔。可以用于计算两个时间对象相差的天数、小时数、分数、秒数、纳秒数;支持LocalTime、LocalDateTime、Instant等时间

public class DurationTest {
    public static void main(String[] args) {
        LocalDateTime start = LocalDateTime.of(2025, 11, 11, 11, 10, 10);
        LocalDateTime end = LocalDateTime.of(2025, 11, 11, 11, 11, 11);
        // 1、得到Duration对象
        Duration duration = Duration.between(start, end);
​
        // 2、获取两个时间对象间隔的信息
        System.out.println(duration.toDays());// 间隔多少天
        System.out.println(duration.toHours());// 间隔多少小时
        System.out.println(duration.toMinutes());// 间隔多少分
        System.out.println(duration.toSeconds());// 间隔多少秒
        System.out.println(duration.toMillis());// 间隔多少毫秒
        System.out.println(duration.toNanos());// 间隔多少纳秒
    }
}

    Logo

    汇聚全球AI编程工具,助力开发者即刻编程。

    更多推荐