为什么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编程工具,助力开发者即刻编程。

    更多推荐