19. JDK8以后的时间类(Date类、日期格式化类、日历类、工具类)

JDK8以后的时间类

  • Date类
      • 1. ZoneID类
        • 1.1 方法
        • 1.2 代码示例
      • 2. Instant类
        • 2.1 方法
        • 2.2 代码示例
      • 3. ZoneDateTime类
        • 3.1 方法
        • 3.2 代码示例
  • 日期格式化类
      • 1. DateTimeFormatter类
        • 1.1 方法
        • 1.2 代码示例
  • 日历类
      • 1. LocalDate类
        • 1.1 方法
        • 1.2 代码示例
      • 2. LocalTime类
        • 2.1 方法
        • 2.2 代码示例
      • 3. LocalDateTime类
        • 3.1 方法
        • 3.2 代码示例
  • 工具类
      • 1. Duration类
        • 1.1 方法
        • 1.2 代码示例
      • 2. Period类
        • 2.1 方法
        • 2.2 代码示例
      • 3. ChronoUnit类
        • 3.1 方法
        • 3.2 代码示例

在这里插入图片描述

Date类

1. ZoneID类

ZoneID类是Java中的一个类,位于java.time包中,用于表示时区的标识符。

  • 时区是以相对于协调世界时(Coordinated Universal Time,UTC)的偏移量来表示地球上不同地区的时间差异。ZoneID类提供了一组静态方法和常量,用于获取和表示时区的标识符。

  • 通过ZoneID类,可以获取当前系统默认的时区,也可以根据特定地区的标识符获取对应的时区。它还可以通过偏移量创建自定义的时区。

  • ZoneID类还与其他日期和时间类紧密配合,可以将日期和时间对象转换为特定时区下的日期和时间,或者将特定时区下的日期和时间转换为其他时区。

需要注意的是,ZoneID类提供的时区标识符是根据区域性的命名约定来命名的,比如"America/New_York"、“Asia/Shanghai"等,而不是简单的”+/-时差的小时数"。

1.1 方法

ZoneId类:时区

静态方法 描述
getAvailableZoneIds() 获取Java中支持的所有时区的标识符
systemDefault() 获取系统默认时区的标识符
of(String zoneId) 根据指定的时区标识符获取ZoneId对象

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间

1.2 代码示例
package text;

import java.time.ZoneId;
import java.util.Set;

/*
ZoneId类:时区
        static Set<string> getAvailableZoneIds() 获取Java中支持的所有时区
        static ZoneId systemDefault() 获取系统默认时区
        static Zoneld of(string zoneld) 获取一个指定时区

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间

 */
public class text89 {
    public static void main(String[] args) {
        //获取支持的时区
        Set<String> set = ZoneId.getAvailableZoneIds();
        //打印集合
        System.out.println(set);//[Asia/Aden,…… US/Pacific, Europe/Monaco]
        //获取集合的长度
        System.out.println(set.size()); //603

        //获取系统默认的时区
        ZoneId zoneId = ZoneId.systemDefault();
        System.out.println(zoneId);  //Asia/Shanghai

        //获取一个指定的时区
        ZoneId of = ZoneId.of("US/Pacific");
        System.out.println(of);    //US/Pacific
    }
}

2. Instant类

Instant类是Java中的一个类,位于java.time包中,用于表示时间戳。时间戳是距离1970年1月1日UTC时间的秒数或纳秒数。

  • Instant类提供了一组方法,用于处理和操作时间戳。它可以表示从1970年1月1日起的精确时间,以纳秒为单位。Instant类是不可变的,也就是说,一旦创建了一个Instant对象,就不能修改它的值。

  • 通过Instant类,可以获取当前的系统时间戳,也可以根据指定的时间戳值创建Instant对象。它还支持与其他日期和时间类的相互转换,可以将Instant对象转换为特定时区下的日期和时间,或者将特定时区下的日期和时间转换为Instant对象。

需要注意的是,Instant类是与计算机系统的时间概念相关的,它与时区无关,并以协调世界时(Coordinated Universal Time,UTC)为基准。

2.1 方法

Instant类:时间戳

静态方法 描述
now() 获取当前标准时间的Instant对象
ofEpochMilli(long epochMilli) 根据指定的毫秒数获取Instant对象
ofEpochSecond(long epochSecond) 根据指定的秒数获取Instant对象
ofEpochSecond(long epochSecond, long nanoAdjustment) 根据指定的秒数和纳秒数获取Instant对象
实例方法 描述
ZonedDateTime atZone(ZoneId zone) 将Instant对象转换为指定时区的ZonedDateTime对象
boolean isXxx(Instant otherInstant) 判断当前Instant对象是否满足指定条件
Instant minusXxx(long millisToSubtract) 从当前Instant对象减去指定的时间间隔
Instant plusXxx(long millisToAdd) 在当前Instant对象上增加指定的时间间隔

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间

2.2 代码示例
package text;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;

/*
Instant类:时间戳
    static Instant now()                            获取当前时间的Instant对象(标准时间)
    static Instant ofXxxx(long epochMilli)          根据(秒/毫秒/纳秒)获取Instant对象

    //以下方法不是静态方法,因此需要创建对象再使用
    ZonedDateTime atZone(ZoneIdzone)                指定时区
    boolean isxxx(Instant otherInstant)             判断系列的方法
    Instant minusXxx(long millisToSubtract)         减少时间系列的方法
    Instant plusXxx(long millisToSubtract)          增加时间系列的方法

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间

 */
public class text90 {
    public static void main(String[] args) {
        //获取当前时间的Instant对象(标准时间)
        Instant now = Instant.now();
        System.out.println(now);       //2024-01-21T08:06:42.049Z


        //根据(秒/毫秒/纳秒)获取Instant对象
        Instant instant1 = Instant.ofEpochSecond(1l);    //根据秒获取Instant对象
        Instant instant2 = Instant.ofEpochMilli(2000l);  // 根据毫秒获取Instant对象
        Instant instant3 = Instant.ofEpochSecond(2l, 1000000000l);    //根据纳秒获取Instant对象
        System.out.println(instant1);   //1970-01-01T00:00:01Z
        System.out.println(instant2);   //1970-01-01T00:00:02Z
        System.out.println(instant3);   //1970-01-01T00:00:03Z


        //指定时区
        ZonedDateTime zonedDateTime = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
        System.out.println(zonedDateTime);   //2024-01-21T16:12:10.778+08:00[Asia/Shanghai]


        //判断系列方法
        //获取对象
        Instant instant4 = Instant.ofEpochSecond(1l);
        Instant instant5 = Instant.ofEpochSecond(2l);
        //isAfter:判断调用者代表的时间是否在参数表示的时间的后面
        boolean after = instant4.isAfter(instant5);
        System.out.println(after);    //false
        //isBefore:判断调用者代表的时间是否在参数表示的时间前面
        boolean before = instant4.isBefore(instant5);
        System.out.println(before);     //true


        //减少时间系列的方法
        //获取对象
        Instant instant6 = Instant.ofEpochSecond(10l);
        System.out.println(instant6);      //1970-01-01T00:00:10Z
        Instant instant7 = instant6.minusSeconds(1l);
        System.out.println(instant7);      //1970-01-01T00:00:09Z


        //增加时间系列的方法
        //获取对象
        Instant instant8 = Instant.ofEpochSecond(10l);
        System.out.println(instant8);      //1970-01-01T00:00:10Z
        Instant instant9 = instant6.plusSeconds(1l);
        System.out.println(instant9);      //1970-01-01T00:00:11Z
    }
}

3. ZoneDateTime类

ZoneDateTime类是Java 8中的一个日期和时间类,它表示带有时区信息的日期和时间。

  • ZoneDateTime类是OffsetDateTime和ZonedDateTime的抽象类。它存储日期、时间和时区信息,并提供了一系列与日期和时间相关的方法。

  • ZoneDateTime类的实例可以使用静态工厂方法从特定的时区、地区、日期和时间构建。它还提供了获取日期、时间、时区、偏移量和UNIX时间戳的方法。

  • ZoneDateTime类还包含用于格式化和解析日期和时间字符串的方法。它可以将日期和时间转换为ISO-8601格式的字符串表示,也可以从ISO-8601格式的字符串解析出日期和时间。

3.1 方法

ZonedDateTime类:带时区的时间

静态方法 描述
static ZonedDateTime now() 获取当前时间的ZonedDateTime对象。
static ZonedDateTime ofXxxx(...) 获取指定时间的ZonedDateTime对象,根据提供的参数来构建对象。
实例方法
ZonedDateTime withXxx(时间) 返回一个修改了特定时间字段的ZonedDateTime对象,例如修改年、月、日、时、分、秒等。
ZonedDateTime minusXxx(时间) 返回一个减少了特定时间字段的ZonedDateTime对象,例如减少年、月、日、时、分、秒等。
ZonedDateTime plusXxx(时间) 返回一个增加了特定时间字段的ZonedDateTime对象,例如增加年、月、日、时、分、秒等。

注意:上述"时间"指的是一定的时间量,可以是年、月、日、时、分、秒等。具体的时间量可根据具体方法而定,例如withYear(int year)修改年份,minusHours(long hours)减少小时数,plusMinutes(long minutes)增加分钟数等。

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间

3.2 代码示例
package text;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;

/*
ZonedDateTime类:带时区的时间
   static ZonedDateTime now()                获取当前时间的ZonedDateTime对象
   static ZonedDateTime ofXxxx(。。。)        获取指定时间的ZonedDateTime对象

   //以下方法不是静态方法,因此需要创建对象再使用
   ZonedDateTime withXxx(时间)                修改时间系列的方法
   ZonedDateTime minusXxx(时间)               减少时间系列的方法
   ZonedDateTime plusXxx(时间)                增加时间系列的方法

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间
 */
public class text91 {
    public static void main(String[] args) {
        //获取当前时间的ZonedDateTime对象(带时区)
        ZonedDateTime now = ZonedDateTime.now();
        System.out.println(now);      //2024-01-21T16:31:29.175+08:00[Asia/Shanghai]


        //获取指定时间的ZonedDateTime对象
        //方式一:年月日时分秒的方式指定
        ZonedDateTime time1 = ZonedDateTime.of(2024, 06, 07, 12, 00, 59, 0, ZoneId.of("Asia/Shanghai"));
        System.out.println(time1);   //2024-06-07T12:00:59+08:00[Asia/Shanghai]

        //方式二:通过Instant + 时区 的方式指定获取时间对象
        //获取Instant对象
        Instant instant = Instant.now();
        //获取时区对象
        ZoneId zoneId = ZoneId.of("Asia/Shanghai");
        ZonedDateTime time2 = ZonedDateTime.ofInstant(instant, zoneId);
        System.out.println(time2);    //2024-01-21T16:37:51.888+08:00[Asia/Shanghai]


        //修改时间系列的方法
        System.out.println(time1);   //2024-06-07T12:00:59+08:00[Asia/Shanghai]
        ZonedDateTime time3 = time1.withYear(2030);
        System.out.println(time3);   //2030-06-07T12:00:59+08:00[Asia/Shanghai]


        //减少时间系列的方法
        System.out.println(time1);  //2024-06-07T12:00:59+08:00[Asia/Shanghai]
        ZonedDateTime time4 = time1.minusYears(1);
        System.out.println(time4);  //2023-06-07T12:00:59+08:00[Asia/Shanghai]


        //增加时间系列的方法
        System.out.println(time1);   //2024-06-07T12:00:59+08:00[Asia/Shanghai]
        ZonedDateTime time5 = time1.plusYears(1);
        System.out.println(time5);   //2025-06-07T12:00:59+08:00[Asia/Shanghai]

    }
}

日期格式化类

1. DateTimeFormatter类

  • DateTimeFormatter类是Java 8中的一个日期和时间格式化类,它用于将日期和时间对象格式化为字符串,或将字符串解析为日期和时间对象。

  • DateTimeFormatter类提供了一系列预定义的格式化模式,用于指定日期和时间的输出格式。例如,可以使用"yyyy-MM-dd"指定年、月、日的格式,或使用"HH:mm:ss"指定小时、分钟、秒的格式。它还支持自定义的格式模式。

  • DateTimeFormatter类还提供了方法来设置和获取不同的字段,例如设置解析时所需的解析上下文,或获取格式化器的本地化信息。

  • DateTimeFormatter类的实例可以使用静态工厂方法创建,也可以使用ofPattern方法根据提供的模式字符串创建。它可以与日期和时间类一起使用,例如LocalDateTime、ZonedDateTime等。

1.1 方法

DateTimeFormatter类:用于时间的格式化和解析

静态方法 描述
static DateTimeFormatter ofPattern(String pattern) 获取具有指定格式的DateTimeFormatter对象。
实例方法
String format(时间对象) 将给定的时间对象按照DateTimeFormatter定义的格式进行格式化,并返回格式化后的字符串。

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间

1.2 代码示例
package text;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

/*
DateTimeFormatter类:用于时间的格式化和解析
   static DateTimeFormatter ofPattern(格式)    获取格式对象
   String format(时间对象)                      按照指定方式格式化

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间
 */
public class text92 {
    public static void main(String[] args) {

        //创建带时区的时间对象
        ZonedDateTime now = ZonedDateTime.now();
        System.out.println(now);     //2024-01-21T16:52:21.868+08:00[Asia/Shanghai]

        //获取格式对象
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss EE a");
        System.out.println(dateTimeFormatter);       //Value(YearOfEra,4,19,EXCEEDS_PAD)'-'Value(MonthOfYear,2)'-'Value(DayOfMonth,2)' 'Value(ClockHourOfAmPm,2)':'Value(MinuteOfHour,2)':'Value(SecondOfMinute,2)' 'Text(DayOfWeek,SHORT)' 'Text(AmPmOfDay,SHORT)


        //按照指定方式格式化
        String format = dateTimeFormatter.format(now);
        System.out.println(format);        //2024-01-21 04:54:47 星期日 下午
    }
}

日历类

1. LocalDate类

LocalDate类是Java 8中的一个日期类,它代表了一个不可变的日期对象,只包含年、月、日的信息,没有时间和时区的部分。

与其它日期类相比,LocalDate类更注重于日期的处理,而不关心具体时间。它提供了一系列方法来处理和操作日期,例如计算两个日期之间的天数差、获取指定日期的年、月、日等。

  • LocalDate类实现了ISO标准的日期,它提供了较为简单且易于使用的API来操作日期。它可以表示从公元前999999999年至公元999999999年之间的日期。

  • LocalDate类是不可变的,这意味着一旦创建了LocalDate对象,就无法修改它的值。而且它也是线程安全的,可以在多线程环境中安全地使用

  • LocalDate类的实例可以通过多种方式创建,例如使用now()方法获取当前日期,使用parse()方法解析字符串得到日期,或使用of()方法根据年、月、日创建日期。

1.1 方法

LocalDate类:年、月、日

静态方法 描述
static LocalDate now() 获取表示当前日期的LocalDate对象。
static LocalDate of(int year, int month, int day) 获取具有指定年、月、日的LocalDate对象。
实例方法
int getYear() 返回LocalDate对象表示的日期的年份。
Month getMonth() 返回LocalDate对象表示的日期的月份,以Month枚举类型表示。
int getMonthValue() 返回LocalDate对象表示的日期的月份值(1-12)。
int getDayOfMonth() 返回LocalDate对象表示的日期的月份中的天数。
DayOfWeek getDayOfWeek() 返回LocalDate对象表示的日期是星期几,以DayOfWeek枚举类型表示。
boolean isBefore(LocalDate otherDate) 判断当前LocalDate是否在另一个LocalDate之前。
boolean isAfter(LocalDate otherDate) 判断当前LocalDate是否在另一个LocalDate之后。
LocalDate withYear(int year) 返回一个新的LocalDate对象,将年份修改为指定值。
LocalDate withMonth(int month) 返回一个新的LocalDate对象,将月份修改为指定值。
LocalDate withDayOfMonth(int day) 返回一个新的LocalDate对象,将日期修改为指定值。
LocalDate minusYears(long years) 返回一个新的LocalDate对象,日期减去指定的年数。
LocalDate minusMonths(long months) 返回一个新的LocalDate对象,日期减去指定的月数。
LocalDate minusDays(long days) 返回一个新的LocalDate对象,日期减去指定的天数。
LocalDate plusYears(long years) 返回一个新的LocalDate对象,日期增加指定的年数。
LocalDate plusMonths(long months) 返回一个新的LocalDate对象,日期增加指定的月数。
LocalDate plusDays(long days) 返回一个新的LocalDate对象,日期增加指定的天数。

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间

1.2 代码示例
package text;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.MonthDay;

/*
LocalDate类:年、月、日
    static LocalDate now()              获取当前对象
    static LocalDate of()               获取指定时间对象
    get开头的方法                         获取日历中的年、月、日
    isBefore、isAfter                    比较两个LocalDate
    with开头的                            修改时间系列的方法,只能修改年月日
    minus开头的                           减少时间系列的方法,只能减少年月日
    plus开头的                            增加时间系列的方法,只能增加年月日
细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间
 */
public class text93 {
    public static void main(String[] args) {
        //获取当前对象
        LocalDate time1 = LocalDate.now();
        System.out.println(time1);    //2024-01-21


        //获取指定时间对象
        LocalDate time2 = LocalDate.of(2024, 12, 26);
        System.out.println(time2);      //2024-12-26


        //获取日历中的年、月、日
        //获取年
        int year = time1.getYear();
        System.out.println(year);       //2024

        //获取月
        //方法一:先创建Month对象再调用getValue方法获取值
        Month month = time1.getMonth();
        int time3 = month.getValue();
        System.out.println(time3);      //1
        //方法二:调用getMonthValue方法
        int time4 = time1.getMonthValue();
        System.out.println(time4);      //1

        //获取日
        int time5 = time1.getDayOfMonth();
        System.out.println(time5);

        //获取一年中的第几天
        int time6 = time1.getDayOfYear();
        System.out.println(time6);

        //获取星期
        DayOfWeek dayOfWeek = time1.getDayOfWeek();
        System.out.println(dayOfWeek);    //SUNDAY  获取的是星期对象
        System.out.println(dayOfWeek.getValue());          //7  获取的是星期中的值


        //比较两个LocalDate
        boolean after = time1.isAfter(time2);     //false
        System.out.println(after);
        boolean before = time1.isBefore(time2);       //true
        System.out.println(before);


        //修改时间系列的方法
        System.out.println(time1);    //2024-01-21
        LocalDate time7 = time1.withYear(2000);
        System.out.println(time7);    //2000-01-21


        //减少时间系列的方法
        System.out.println(time1);    //2024-01-21
        LocalDate time8 = time1.minusYears(10);
        System.out.println(time8);      //2014-01-21


        //增加时间系列的方法
        System.out.println(time1);    //2024-01-21
        LocalDate time9 = time1.plusYears(5);
        System.out.println(time9);       //2029-01-21


        //判断今天是否是你的生日
        judge();
    }

    public static void judge() {
        //创建生日时间对象
        LocalDate date1 = LocalDate.of(2000, 11, 21);
        System.out.println(date1);  //2000-11-21
        //获取生日时间对象的月、日
        MonthDay monthDay1 = MonthDay.of(date1.getMonth(), date1.getDayOfMonth());
        //获取今天时间对象
        LocalDate date2 = LocalDate.now();
        System.out.println(date2);    //2024-01-21
        //获取今天时间对象的月、日
        MonthDay monthDay2 = MonthDay.from(date2);

        if (monthDay1.equals(monthDay2)) {
            System.out.println("今天是你的生日!");
        } else {
            System.out.println("今天不是你的是生日!");
        }
    }
}

2. LocalTime类

LocalTime类是Java 8中引入的日期和时间API中的一个类,用于表示时间,不包含日期和时区信息。它是不可变的(immutable)类,可以直接创建实例,也可以从其他日期时间类中提取出来。

  • LocalTime类提供了一系列的静态工厂方法和实例方法,用于创建、操作和格式化时间。它可以表示从00:00:00到23:59:59之间的时间。
2.1 方法

LocalTime类:时、分、秒

方法签名 描述
static LocalTime now() 获取当前时间对象
static LocalTime of(int hour, int minute) 创建指定的时间对象
int getHour() 获取时间的小时部分
int getMinute() 获取时间的分钟部分
int getSecond() 获取时间的秒部分
boolean isBefore(LocalTime other) 比较当前时间是否在另一个时间之前
boolean isAfter(LocalTime other) 比较当前时间是否在另一个时间之后
LocalTime withHour(int hour) 返回一个新的LocalTime对象,将小时部分设置为指定值
LocalTime withMinute(int minute) 返回一个新的LocalTime对象,将分钟部分设置为指定值
LocalTime withSecond(int second) 返回一个新的LocalTime对象,将秒部分设置为指定值
LocalTime minusHours(long hours) 返回一个新的LocalTime对象,在当前时间上减去指定的小时数
LocalTime minusMinutes(long minutes) 返回一个新的LocalTime对象,在当前时间上减去指定的分钟数
LocalTime minusSeconds(long seconds) 返回一个新的LocalTime对象,在当前时间上减去指定的秒数
LocalTime plusHours(long hours) 返回一个新的LocalTime对象,在当前时间上增加指定的小时数
LocalTime plusMinutes(long minutes) 返回一个新的LocalTime对象,在当前时间上增加指定的分钟数
LocalTime plusSeconds(long seconds) 返回一个新的LocalTime对象,在当前时间上增加指定的秒数

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间

2.2 代码示例
package text;

import java.time.LocalTime;

/*
LocalTime类:时、分、秒
    static LocalTime now()              获取当前对象
    static LocalTime of()               获取指定时间对象
    get开头的方法                         获取日历中的年、月、日
    isBefore、isAfter                    比较两个LocalTime
    with开头的                            修改时间系列的方法, 只能修改时分秒
    minus开头的                           减少时间系列的方法,只能减少时分秒
    plus开头的                            增加时间系列的方法,只能增加时分秒
细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间
 */
public class text94 {
    public static void main(String[] args) {
        // 获取本地时间的日历对象。(包含 时分秒)
        LocalTime nowTime = LocalTime.now();
        System.out.println("今天的时间:" + nowTime);     //今天的时间:17:55:06.894

        int hour = nowTime.getHour();//时
        System.out.println("hour: " + hour);      //hour: 17

        int minute = nowTime.getMinute();//分
        System.out.println("minute: " + minute);    //minute: 55

        int second = nowTime.getSecond();//秒
        System.out.println("second:" + second);        //second:6

        int nano = nowTime.getNano();//纳秒
        System.out.println("nano:" + nano);          //nano:894000000

        System.out.println(LocalTime.of(8, 20));//时分  08:20
        System.out.println(LocalTime.of(8, 20, 30));//时分秒   08:20:30
        System.out.println(LocalTime.of(8, 20, 30, 150));//时分秒纳秒   08:20:30.000000150


        LocalTime mTime = LocalTime.of(8, 20, 30, 150);
        //is系列的方法
        System.out.println(nowTime.isBefore(mTime));     //false
        System.out.println(nowTime.isAfter(mTime));      //true

        //with系列的方法,只能修改时、分、秒
        System.out.println(nowTime.withHour(10));        //10:55:06.894

        //plus系列的方法,只能增加时、分、秒
        System.out.println(nowTime.plusHours(3));       //20:55:06.894
    }
}

3. LocalDateTime类

LocalDateTime类是Java 8中引入的日期和时间API中的一个类,用于表示日期和时间,不包含时区信息。它是不可变的(immutable)类,可以直接创建实例,也可以从其他日期时间类中提取出来。

  • LocalDateTime类是LocalDate和LocalTime类的结合,表示一个完整的日期和时间,包括年、月、日、时、分、秒。它提供了一系列的静态工厂方法和实例方法,用于创建、操作和格式化日期和时间。
3.1 方法

LocalDateTime类:年、月、日、时、分、秒

方法 描述
toLocalDate() 将LocalDateTime转换为LocalDate对象
toLocalTime() 将LocalDateTime转换为LocalTime对象
now() 获取当前的日期和时间
of(int year, int month, int dayOfMonth, int hour, int minute) 创建指定的日期和时间
getYear() 获取年份部分
getMonth() 获取月份部分
getDayOfMonth() 获取月份中的日期部分
getHour() 获取小时部分
getMinute() 获取分钟部分
getSecond() 获取秒部分
isBefore(LocalDateTime other) 比较两个LocalDateTime是否在指定的时间之前
isAfter(LocalDateTime other) 比较两个LocalDateTime是否在指定的时间之后
withYear(int year) 修改年份部分
withMonth(int month) 修改月份部分
withDayOfMonth(int dayOfMonth) 修改月份中的日期部分
withHour(int hour) 修改小时部分
withMinute(int minute) 修改分钟部分
withSecond(int second) 修改秒部分
minusDays(long days) 减去指定的天数
minusHours(long hours) 减去指定的小时数
minusMinutes(long minutes) 减去指定的分钟数
plusDays(long days) 增加指定的天数
plusHours(long hours) 增加指定的小时数
plusMinutes(long minutes) 增加指定的分钟数

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间

3.2 代码示例
package text;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/*
LocalDateTime类:年、月、日、时、分、秒
将LocalDateTime转换成LocalDate对象:
    public LocalDate toLocalDate()
将LocalDateTime转换成LocalTime对象:
    public LocalTime toLocalTime()
方法:
    static LocalDateTime now()           获取当前对象
    static LocalDateTime of()            获取指定时间对象
    get开头的方法                          获取日历中的年、月、日、时、分、秒、纳秒
    isBefore、isAfter                    比较两个LocalDateTime
    with开头的                            修改时间系列的方法
    minus开头的                           减少时间系列的方法
    plus开头的                            增加时间系列的方法

细节:JDK8新增的时间对象都是不可变的,如果我们修改了时间,那么调用者不会改变,而是产生一个新的时间

 */
public class text95 {
    public static void main(String[] args) {
        // 当前时间的的日历对象(包含年月日时分秒)
        LocalDateTime nowDateTime = LocalDateTime.now();
        //获取当前时间 年、月、日、时、分、秒
        System.out.println("今天是:" + nowDateTime);//今天是:2024-01-21T18:02:25.426
        //获取日历中的年、月、日、时、分、秒、纳秒
        System.out.println(nowDateTime.getYear());//年   2024
        System.out.println(nowDateTime.getMonthValue());//月     1
        System.out.println(nowDateTime.getDayOfMonth());//日     21
        System.out.println(nowDateTime.getHour());//时      18
        System.out.println(nowDateTime.getMinute());//分     2
        System.out.println(nowDateTime.getSecond());//秒     25
        System.out.println(nowDateTime.getNano());//纳秒     426000000


        // 日:当年的第几天
        System.out.println("dayofYear:" + nowDateTime.getDayOfYear());      //dayofYear:21

        //星期
        System.out.println(nowDateTime.getDayOfWeek());       //SUNDAY
        System.out.println(nowDateTime.getDayOfWeek().getValue());      //7

        //月份
        System.out.println(nowDateTime.getMonth());     //JANUARY
        System.out.println(nowDateTime.getMonth().getValue());      //1

        //将LocalDateTime转换成LocalDate对象
        LocalDate ld = nowDateTime.toLocalDate();
        System.out.println(ld);       //2024-01-21
        System.out.println(ld.getYear());     //2024
        System.out.println(ld.getMonthValue());    //1
        System.out.println(ld.getDayOfMonth());     //21

        //将LocalDateTime转换成LocalTime对象
        LocalTime lt = nowDateTime.toLocalTime();
        System.out.println(lt);     //18:02:25.426
        System.out.println(lt.getHour());      //18
        System.out.println(lt.getMinute());     //02
        System.out.println(lt.getSecond());      //25
    }
}

工具类

1. Duration类

Duration类是一个表示时间间隔的类。它主要用于在程序中跟踪和处理时间上的差异或持续时间。

  • Duration类提供了各种方法和属性,用于计算、转换和比较时间间隔。它可以表示以不同单位(如秒、毫秒、纳秒等)表示的时间间隔,并提供了将时间间隔转换为不同单位的方法。
  • 此外,Duration类还可以执行加法、减法和乘法来计算时间间隔的运算,以及判断时间间隔是否为负数或零等操作。

在Java中,Duration类是java.time包中的一部分,它是Java 8引入的日期和时间API的一部分。它提供了更直观、易于>使用和可靠的方式来处理日期和时间,以替代旧的Date和Calendar类。

1.1 方法
方法 描述
ofDays(long days) 创建一个以指定天数为单位的Duration对象
ofHours(long hours) 创建一个以指定小时数为单位的Duration对象
ofMinutes(long minutes) 创建一个以指定分钟数为单位的Duration对象
ofSeconds(long seconds) 创建一个以指定秒数为单位的Duration对象
ofMillis(long millis) 创建一个以指定毫秒数为单位的Duration对象
ofNanos(long nanos) 创建一个以指定纳秒数为单位的Duration对象
plus(Duration duration) 将指定的Duration对象与当前对象相加,并返回新的Duration对象
minus(Duration duration) 将指定的Duration对象与当前对象相减,并返回新的Duration对象
multipliedBy(long multiplicand) 将当前对象的值乘以指定的数,并返回新的Duration对象
dividedBy(long divisor) 将当前对象的值除以指定的数,并返回新的Duration对象
compareTo(Duration other) 比较当前对象与指定的Duration对象的大小关系
isNegative() 判断当前对象的值是否为负数
isZero() 判断当前对象的值是否为零
toDays() 将当前对象的值转换为天数
toHours() 将当前对象的值转换为小时数
toMinutes() 将当前对象的值转换为分钟数
toSeconds() 将当前对象的值转换为秒数
toMillis() 将当前对象的值转换为毫秒数
toNanos() 将当前对象的值转换为纳秒数
1.2 代码示例
package text;

import java.time.Duration;
import java.time.LocalDateTime;

/*
Duration  时间间隔(秒,纳,秒)
 */
public class text96 {
    public static void main(String[] args) {
        // 本地日期时间对象。
        LocalDateTime today = LocalDateTime.now();
        System.out.println(today);         //2024-01-21T18:17:36.008

        // 出生的日期时间对象
        LocalDateTime birthDate = LocalDateTime.of(2030, 11, 21, 0, 0, 0);
        System.out.println(birthDate);         //2030-11-21T00:00

        //调用Duration中的between方法
        Duration duration = Duration.between(today, birthDate);//第二个参数减第一个参数
        System.out.println("相差的时间间隔对象:" + duration);          //相差的时间间隔对象:PT59885H42M23.992S

        System.out.println(duration.toDays());//两个时间差的天数     2495
        System.out.println(duration.toHours());//两个时间差的小时数      59885
        System.out.println(duration.toMinutes());//两个时间差的分钟数       3593142
        System.out.println(duration.toMillis());//两个时间差的毫秒数       215588543992
        System.out.println(duration.toNanos());//两个时间差的纳秒数         215588543992000000
    }
}

2. Period类

Period类是Java中的一个类,用于表示日期间隔。它主要用于在程序中处理和计算日期的差异。

  • Period类提供了一种方便的方式来表示日期的差异,例如年份、月份和天数。它可以用于计算两个日期之间的时间间隔,或者添加或减去特定的年、月和日数量。

  • Period类是不可变的,意味着一旦创建了一个Period对象,它的值是不能更改的。这样设计的好处是保证了其线程安全性。

在Java中,Period类是java.time包中的一部分,它是Java 8引入的日期和时间API的一部分。它提供了更直观、易于使用和可靠的方式来处理日期和时间,以替代旧的Date和Calendar类。

2.1 方法
方法 描述
ofYears(int years) 创建一个以指定年数为单位的Period对象
ofMonths(int months) 创建一个以指定月数为单位的Period对象
ofWeeks(int weeks) 创建一个以指定周数为单位的Period对象
ofDays(int days) 创建一个以指定天数为单位的Period对象
plus(Period other) 将指定的Period对象与当前对象相加,并返回新的Period对象
minus(Period other) 将指定的Period对象与当前对象相减,并返回新的Period对象
multipliedBy(int scalar) 将当前对象的值乘以指定的数,并返回新的Period对象
normalized() 标准化当前Period对象,将月份和天数进行调整
addTo(Temporal temporal) 将当前Period对象加到指定的Temporal对象上,并返回新的Temporal对象
getDays() 获取Period对象表示的天数
getMonths() 获取Period对象表示的月数
getYears() 获取Period对象表示的年数
isNegative() 判断当前Period对象的值是否为负数
isZero() 判断当前Period对象的值是否为零
2.2 代码示例
package text;

import java.time.LocalDate;
import java.time.Period;

/*
Period  时间间隔(年,月,日)
 */
public class text97 {
    public static void main(String[] args) {
        // 当前本地 年月日
        LocalDate today = LocalDate.now();
        System.out.println(today);        //2024-01-21

        // 生日的 年月日
        LocalDate birthDate = LocalDate.of(2030, 11, 21);
        System.out.println(birthDate);        //2030-11-21

        //调用Period中的between方法
        Period period = Period.between(today,birthDate);//第二个参数减第一个参数

        System.out.println("相差的时间间隔对象:" + period);        //相差的时间间隔对象:P6Y10M
        System.out.println(period.getYears());        //6
        System.out.println(period.getMonths());       //10
        System.out.println(period.getDays());         //0

        System.out.println(period.toTotalMonths());      //82
    }
}

3. ChronoUnit类

ChronoUnit类是Java中的一个枚举类,用于表示日期和时间的不同单位。它是Java 8引入的日期和时间API的一部分,位于java.time包中。

  • ChronoUnit类定义了一组预定义的时间单位,可以用来计算和处理日期和时间的差异。这些时间单位包括年、月、周、日、小时、分钟、秒等等。它提供了一种便捷的方式来操作和计算日期和时间。

  • 使用ChronoUnit类,您可以计算两个日期之间的时间差异,并以指定的时间单位返回结果。您还可以将日期增加或减少指定的单位数量,或者获取指定时间单位的持续时间。

  • ChronoUnit类还提供了一些其他的方法,用于获取单位的名称、获取单位的持续时间长度、比较两个单位的顺序等等。

3.1 方法
方法 描述
between(Temporal start, Temporal end) 计算两个Temporal对象之间的时间差异,并返回以指定的ChronoUnit单位表示的结果
addTo(Temporal temporal, long amount) 将指定的数量添加到Temporal对象,并返回新的Temporal对象
subtractFrom(Temporal temporal, long amount) 从Temporal对象中减去指定的数量,并返回新的Temporal对象
isDurationEstimated() 判断此ChronoUnit单位的持续时间是否是估计值
getDuration() 获取此ChronoUnit单位的持续时间
getDisplayName() 获取此ChronoUnit单位的显示名称
getDuration().toTemporals() 获取此ChronoUnit单位的有效时间单位列表
isDateBased() 判断此ChronoUnit单位是否属于日期单位
isTimeBased() 判断此ChronoUnit单位是否属于时间单位
compareTo() 比较两个ChronoUnit单位的顺序
values() 获取所有的ChronoUnit枚举常量
3.2 代码示例
package text;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

/*
 ChronoUnit  时间间隔(所有单位)
 */
public class text98 {
    public static void main(String[] args) {
        // 当前时间
        LocalDateTime today = LocalDateTime.now();
        System.out.println(today);        //2024-01-21T18:21:13.970
        // 生日时间
        LocalDateTime birthDate = LocalDateTime.of(2010, 11, 21, 0, 0, 0);
        System.out.println(birthDate);         //2010-11-21T00:00

        //调用ChronoUnit中的between方法
        System.out.println("相差的年数:" + ChronoUnit.YEARS.between(birthDate, today));     //相差的年数:13
        System.out.println("相差的月数:" + ChronoUnit.MONTHS.between(birthDate, today));    // 相差的月数:158
        System.out.println("相差的周数:" + ChronoUnit.WEEKS.between(birthDate, today));      //相差的周数:687
        System.out.println("相差的天数:" + ChronoUnit.DAYS.between(birthDate, today));       //  相差的天数:4809
        System.out.println("相差的时数:" + ChronoUnit.HOURS.between(birthDate, today));        //相差的时数:115434
        System.out.println("相差的分数:" + ChronoUnit.MINUTES.between(birthDate, today));      //相差的分数:6926061
        System.out.println("相差的秒数:" + ChronoUnit.SECONDS.between(birthDate, today));       //相差的秒数:415563673
        System.out.println("相差的毫秒数:" + ChronoUnit.MILLIS.between(birthDate, today));      //相差的毫秒数:415563673970
        System.out.println("相差的微秒数:" + ChronoUnit.MICROS.between(birthDate, today));      // 相差的微秒数:415563673970000
        System.out.println("相差的纳秒数:" + ChronoUnit.NANOS.between(birthDate, today));        //相差的纳秒数:415563673970000000
        System.out.println("相差的半天数:" + ChronoUnit.HALF_DAYS.between(birthDate, today));      // 相差的半天数:9619
        System.out.println("相差的十年数:" + ChronoUnit.DECADES.between(birthDate, today));        // 相差的十年数:1
        System.out.println("相差的世纪(百年)数:" + ChronoUnit.CENTURIES.between(birthDate, today));     // 相差的世纪(百年)数:0
        System.out.println("相差的千年数:" + ChronoUnit.MILLENNIA.between(birthDate, today));      //相差的千年数:0
        System.out.println("相差的纪元数:" + ChronoUnit.ERAS.between(birthDate, today));       // 相差的纪元数:0
    }
}