Java8新特性之时间类两万字详细

第一章 Date类

1.1 Date概述

java.util.Date 类表示一个特定的时刻,精确到毫秒。

当我们查看 Date 类的描述时,发现它提供了多个构造函数,但部分已经过时。这里我们重点关注两个常用的构造函数:

  • public Date():创建一个表示当前系统时间的 Date 对象,内部以毫秒为单位记录自时间原点(1970年1月1日00:00:00 GMT)到当前时刻的毫秒数。
  • public Date(long date):使用指定的毫秒值创建 Date 对象。此毫秒值代表自标准基准时间(1970年1月1日00:00:00 GMT)以来的时间。

注意:由于中国位于东八区(GMT+08:00),比世界协调时间(GMT)快8小时。因此,当格林尼治标准时间为 0:00 时,东八区的标准时间为 08:00。

简单来说,使用无参构造函数可以自动生成当前系统时间的 Date 对象,而指定 long 类型的构造参数可以自定义一个特定的毫秒时刻。例如:

示例代码:

import java.util.Date;

public class Demo01Date {
    
    
    public static void main(String[] args) {
    
    
        // 创建一个Date对象,表示当前系统时间
        Date currentDate = new Date();
        System.out.println(currentDate); // Tue Jan 16 14:37:35 CST 2020

        // 创建一个Date对象,表示1970年1月1日08:00:00的时间
        Date epochDate = new Date(0L);
        System.out.println(epochDate); // Thu Jan 01 08:00:00 CST 1970
    }
}

输出结果:

Tue Jan 16 14:37:35 CST 2020
Thu Jan 01 08:00:00 CST 1970

注意:当使用 println 方法时,Date 类会自动调用其覆盖的 toString() 方法,将 Date 对象转换为指定格式的字符串输出。

第二章 SimpleDateFormat类

java.text.SimpleDateFormat 是用于日期/时间格式化的类,能够完成日期和字符串之间的相互转换,即可以在 Date 对象与 String 对象之间进行双向转换。

  • 格式化:将 Date 对象转换为符合指定格式的字符串。
  • 解析:将符合指定格式的字符串解析为 Date 对象。

2.1 构造方法

由于 DateFormat 是一个抽象类,不能直接实例化,所以我们使用 java.text.SimpleDateFormat 这个子类。SimpleDateFormat 需要提供一个模式字符串来指定格式化或解析的标准。常用构造方法如下:

  • public SimpleDateFormat(String pattern):使用指定的模式创建 SimpleDateFormat 实例。pattern 是一个字符串,定义了日期和时间的格式。

2.2 格式规则

在格式化和解析日期时,pattern 参数包含的格式化符号如下:

标识字母(区分大小写) 含义
y
M
d
H 时(24小时制)
h 时(12小时制)
m
s
S 毫秒
E 星期几
z 时区

提示:更多的格式化符号可以参考 SimpleDateFormat 类的官方 API 文档。

2.3 常用方法

DateFormat 类的常用方法如下:

  • public String format(Date date):将 Date 对象格式化为字符串。
  • public Date parse(String source):将字符串解析为 Date 对象。

代码示例:

package com.example.datedemo;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatDemo {
    
    
    public static void main(String[] args) throws ParseException {
    
    
        // 1. 定义一个字符串表示时间
        String str = "2023-11-11 11:11:11";

        // 2. 利用构造方法创建 SimpleDateFormat 对象,指定格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        // 3. 将字符串解析为 Date 对象
        Date date = sdf.parse(str);

        // 4. 打印 Date 对象的毫秒值
        System.out.println(date.getTime()); // 输出:1699672271000

        // 5. 将当前时间格式化为指定格式的字符串
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss E z");
        String formattedDate = sdf2.format(new Date());
        System.out.println(formattedDate);  // 格式化并输出当前时间
    }
}

小结

  • SimpleDateFormat 类可以用来将日期和字符串相互转换。format 方法可以将 Date 对象转换为字符串,parse 方法则可以将字符串解析为 Date 对象。

2.4 练习1:初恋女友的出生日期

/*
    假设你初恋的出生日期是 2000-11-11
    请使用字符串表示该日期,并将其转换为 "2000年11月11日"
*/

public class BirthdayExample {
    
    
    public static void main(String[] args) throws ParseException {
    
    
        // 1. 使用字符串表示日期
        String str = "2000-11-11";

        // 2. 创建 SimpleDateFormat 对象,使用 "yyyy-MM-dd" 格式解析
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdf1.parse(str);

        // 3. 创建 SimpleDateFormat 对象,使用 "yyyy年MM月dd日" 格式格式化
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日");
        String result = sdf2.format(date);

        // 4. 输出结果
        System.out.println(result); // 输出:2000年11月11日
    }
}

补充说明:在日期格式转换过程中,要确保 SimpleDateFormatpattern 与输入字符串的格式完全一致。否则会抛出 ParseException 异常。

2.5 SimpleDateFormat 的线程安全问题

SimpleDateFormat 在多线程环境下并不是线程安全的。为了避免数据不一致的问题,通常有两种解决方案:

  1. 每个线程使用独立的 SimpleDateFormat 实例
  2. 使用 ThreadLocal<SimpleDateFormat> 进行线程隔离。

示例:

private static final ThreadLocal<SimpleDateFormat> threadLocalSdf = 
    ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));

public static String formatDate(Date date) {
    
    
    return threadLocalSdf.get().format(date);
}

public static Date parseDate(String dateStr) throws ParseException {
    
    
    return threadLocalSdf.get().parse(dateStr);
}

这样可以确保每个线程使用独立的 SimpleDateFormat 实例,避免线程安全问题。

第三章 Calendar类

java.util.Calendar 类是 Java 中用于处理日期和时间的类,它提供了丰富的 API 来实现日期的获取、设置和运算。Calendar 是一个抽象类,通常通过它的子类 java.util.GregorianCalendar 实例化。Calendar 类的出现弥补了 Date 类的一些不足之处,比如直接获取年、月、日、时、分、秒等字段的值。

3.1 概述

  • java.util.Calendar 类表示的是一个“日历类”,它提供了非常便捷的方法来获取日期字段的值、进行日期运算等。
  • Calendar 是一个抽象类,我们可以使用 Calendar.getInstance() 来获取它的子类 GregorianCalendar 的实例。

3.2 常用方法

方法名 说明
public static Calendar getInstance() 获取一个 GregorianCalendar 对象(Calendar 的子类)。
public int get(int field) 获取指定字段的值,field 参数指定要获取的字段,如 Calendar.YEAR 表示年,Calendar.MONTH 表示月等。
public void set(int field, int value) 设置指定字段的值。
public void add(int field, int value) 为指定字段增加或减少一定的值(正值表示增加,负值表示减少)。

3.3 get 方法示例

get 方法用于获取日历中的某个字段的值,如年、月、日等。

import java.util.Calendar;

public class CalendarDemo {
    
    
    public static void main(String[] args) {
    
    
        // 获取一个 Calendar 对象
        Calendar calendar = Calendar.getInstance();

        // 获取年、月、日、小时、分钟、秒、星期
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1; // Calendar 的月份从 0 开始,所以要加 1
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY); // 24 小时制
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        int week = calendar.get(Calendar.DAY_OF_WEEK); // 1--7,分别表示星期日到星期六

        // 输出日期时间信息
        System.out.println(year + "年" + month + "月" + day + "日 " + hour + ":" + minute + ":" + second);
        System.out.println("今天是:" + getWeek(week));
    }

    // 查询星期几
    public static String getWeek(int dayOfWeek) {
    
    
        String[] weekDays = {
    
    "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        return weekDays[dayOfWeek - 1];
    }
}

3.4 set 方法示例

set 方法用于设置日历中的某个字段的值。

import java.util.Calendar;

public class CalendarSetDemo {
    
    
    public static void main(String[] args) {
    
    
        // 获取一个 Calendar 对象
        Calendar calendar = Calendar.getInstance();

        // 设置年、月、日
        calendar.set(Calendar.YEAR, 1998);
        calendar.set(Calendar.MONTH, 2); // 月份从 0 开始,3 月要设为 2
        calendar.set(Calendar.DAY_OF_MONTH, 18);

        // 获取班长出生那天是星期几
        int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
        System.out.println("班长出生那天是:" + getWeek(weekDay));
    }

    // 查询星期几
    public static String getWeek(int dayOfWeek) {
    
    
        String[] weekDays = {
    
    "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        return weekDays[dayOfWeek - 1];
    }
}

在这个示例中,我们通过 set 方法设置了班长的出生日期为 1998 年 3 月 18 日,并且通过 get 方法获取这一天是星期几。

3.5 add 方法示例

add 方法用于为指定的字段增加或减少值。

import java.util.Calendar;

public class CalendarAddDemo {
    
    
    public static void main(String[] args) {
    
    
        // 获取当前日期
        Calendar calendar = Calendar.getInstance();

        // 计算200天后的日期
        calendar.add(Calendar.DAY_OF_MONTH, 200);

        // 获取年、月、日
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1; // 月份从 0 开始,所以要加 1
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        // 获取星期几
        int weekDay = calendar.get(Calendar.DAY_OF_WEEK);

        // 输出结果
        System.out.println("200天后是:" + year + "年" + month + "月" + day + "日 " + getWeek(weekDay));
    }

    // 查询星期几
    public static String getWeek(int dayOfWeek) {
    
    
        String[] weekDays = {
    
    "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        return weekDays[dayOfWeek - 1];
    }
}

3.6 Calendar 类的补充

3.6.1 获取时间戳

可以通过 Calendar 对象获取对应的时间戳(从 1970 年 1 月 1 日到当前时间的毫秒数):

Calendar calendar = Calendar.getInstance();
long timeInMillis = calendar.getTimeInMillis();
System.out.println("当前时间的时间戳:" + timeInMillis);
3.6.2 重置 Calendar

可以通过 clear() 方法重置 Calendar 的所有字段:

Calendar calendar = Calendar.getInstance();
calendar.clear(); // 重置所有字段
calendar.set(Calendar.YEAR, 2022); // 重新设置年份
System.out.println("重新设置后的年份:" + calendar.get(Calendar.YEAR));

小结

  • Calendar 类提供了更加灵活的方法来操作日期和时间,可以直接获取和设置年、月、日等字段。
  • 通过 add 方法可以进行日期的运算,例如增加或减少天数。
  • getInstance 方法是获取 Calendar 对象的常用方式,它返回的是 GregorianCalendar 的实例。

很抱歉给你带来了困扰,我理解你希望不仅仅看到代码示例,还希望看到解释和补充内容。让我来逐步为每个时间相关的类添加简要的文字说明和解释,以便你更好地理解每个类的用法和场景。


第四章 JDK8 时间相关类

Java 8 引入了一套全新的日期和时间 API,它解决了旧版 DateCalendar 类的缺陷,并且更加直观、简洁和线程安全。这些类位于 java.time 包中。接下来我们会逐一讲解主要的时间相关类及其功能。

JDK8 时间类名 功能描述
ZoneId 时区
Instant 时间戳
ZonedDateTime 带时区的时间
DateTimeFormatter 时间格式化与解析
LocalDate 仅包含日期(年、月、日)
LocalTime 仅包含时间(时、分、秒)
LocalDateTime 包含日期和时间(年、月、日、时、分、秒)
Duration 时间间隔(秒、纳秒)
Period 时间间隔(年、月、日)
ChronoUnit 时间间隔(不同单位)

4.1 ZoneId 时区类

ZoneId 用于表示一个时区,它可以帮助我们在全球不同的时区之间进行时间计算和转换。

常见的用法:

  1. 获取系统默认时区。
  2. 获取所有支持的时区。
  3. 创建一个特定的时区。

代码示例:

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

public class ZoneIdDemo {
    
    
    public static void main(String[] args) {
    
    
        // 1. 获取所有可用的时区ID
        Set<String> zoneIds = ZoneId.getAvailableZoneIds();
        System.out.println("所有时区ID数量: " + zoneIds.size());
        System.out.println("所有时区ID: " + zoneIds);

        // 2. 获取系统默认时区
        ZoneId defaultZoneId = ZoneId.systemDefault();
        System.out.println("系统默认时区: " + defaultZoneId);

        // 3. 获取指定的时区
        ZoneId specifiedZoneId = ZoneId.of("Asia/Shanghai");
        System.out.println("指定时区: " + specifiedZoneId);
    }
}

解释:

  • ZoneId.getAvailableZoneIds() 返回所有支持的时区 ID。
  • ZoneId.systemDefault() 返回系统默认的时区(如 Asia/Shanghai)。
  • ZoneId.of(String) 根据给定的时区名称获取相应的时区。

4.2 Instant 时间戳类

Instant 类代表时间戳,指自 1970-01-01 00:00:00(UTC) 起至现在的时间,精确到纳秒。它类似于旧的 Date 类,但功能更强大。

常见的用法:

  1. 获取当前的时间戳。
  2. 从秒或毫秒值创建 Instant 对象。
  3. 比较两个时间戳之间的先后。

代码示例:

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

public class InstantDemo {
    
    
    public static void main(String[] args) {
    
    
        // 1. 获取当前的时间戳
        Instant now = Instant.now();
        System.out.println("当前时间戳: " + now);

        // 2. 将毫秒值转换为Instant对象
        Instant fromMillis = Instant.ofEpochMilli(0L);
        System.out.println("1970-01-01 00:00:00的时间戳: " + fromMillis);

        // 3. 将秒值转换为Instant对象
        Instant fromSeconds = Instant.ofEpochSecond(1L);
        System.out.println("1970-01-01 00:00:01的时间戳: " + fromSeconds);

        // 4. 指定时区转换为带时区的时间对象
        ZonedDateTime timeInShanghai = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
        System.out.println("当前时间(上海时区): " + timeInShanghai);

        // 5. 判断时间先后
        Instant earlier = Instant.ofEpochMilli(0L);
        Instant later = Instant.ofEpochMilli(1000L);
        System.out.println("earlier是否在later之前: " + earlier.isBefore(later));
    }
}

解释:

  • Instant.now() 获取当前时间的时间戳。
  • Instant.ofEpochMilli(0L) 表示从 1970-01-01 00:00:00 开始经过的毫秒数为 0 时的时间戳。
  • Instant.ofEpochSecond(1L) 表示从 1970-01-01 00:00:00 开始经过的秒数为 1 时的时间戳。

4.3 ZonedDateTime 带时区的时间

ZonedDateTime 是一个包含时区的日期时间类,适用于需要处理带有时区的时间的场景,比如全球时区转换。

常见的用法:

  1. 获取当前的带时区的时间。
  2. 指定时间和时区,创建 ZonedDateTime 对象。
  3. 修改 ZonedDateTime 对象中的日期或时间。

代码示例:

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

public class ZonedDateTimeDemo {
    
    
    public static void main(String[] args) {
    
    
        // 1. 获取当前时间(带时区)
        ZonedDateTime now = ZonedDateTime.now();
        System.out.println("当前时间(带时区): " + now);

        // 2. 指定日期时间与时区
        ZonedDateTime specificTime = ZonedDateTime.of(2023, 10, 1, 11, 12, 0, 0, ZoneId.of("Asia/Shanghai"));
        System.out.println("指定时间(带时区): " + specificTime);

        // 3. Instant与时区结合获取时间
        Instant instant = Instant.ofEpochMilli(0L);
        ZonedDateTime zonedFromInstant = ZonedDateTime.ofInstant(instant, ZoneId.of("Asia/Shanghai"));
        System.out.println("1970-01-01 08:00(上海时区): " + zonedFromInstant);

        // 4. 修改年份
        ZonedDateTime modifiedYear = zonedFromInstant.withYear(2000);
        System.out.println("修改年份后的时间: " + modifiedYear);

        // 5. 增加一年
        ZonedDateTime oneYearLater = modifiedYear.plusYears(1);
        System.out.println("增加一年后的时间: " + oneYearLater);
    }
}

解释:

  • ZonedDateTime.now() 获取当前时间,包含时区信息。
  • ZonedDateTime.of(...) 创建一个带有时区的指定时间对象。
  • withXxx() 修改指定部分的时间。
  • plusXxx() 增加指定的时间单位。

好的,我会继续为后续的类进行详细的解释与补充说明。


4.4 DateTimeFormatter 时间格式化与解析

DateTimeFormatter 类用于格式化和解析日期、时间。它可以将 LocalDateTimeLocalDateLocalTime 格式化为字符串,也可以从特定格式的字符串中解析出日期或时间对象。

常见的用法:

  1. 格式化日期和时间对象为字符串。
  2. 从字符串解析出日期和时间对象。

代码示例:

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

public class DateTimeFormatterDemo {
    
    
    public static void main(String[] args) {
    
    
        // 1. 获取当前时间(带时区)
        ZonedDateTime now = ZonedDateTime.now();

        // 2. 创建一个格式化器,定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss a");

        // 3. 格式化当前时间为字符串
        String formattedDate = now.format(formatter);
        System.out.println("格式化后的时间: " + formattedDate);

        // 4. 解析字符串为日期时间对象
        String dateStr = "2023-10-01 08:00:00 AM";
        ZonedDateTime parsedDate = ZonedDateTime.parse(dateStr, formatter);
        System.out.println("解析后的时间: " + parsedDate);
    }
}

解释:

  • DateTimeFormatter.ofPattern() 创建一个格式化器对象,指定时间日期格式。
  • format() 方法将时间对象格式化为字符串。
  • parse() 方法根据指定格式将字符串解析为 ZonedDateTime 对象。

4.5 LocalDate 年、月、日

LocalDate 类表示日期对象,只包含 年、月、日,不包含时间信息。这类对象通常用于表示一个完整的日期,比如生日、纪念日等。

常见的用法:

  1. 获取当前日期。
  2. 获取指定的日期对象。
  3. 修改日期或进行日期比较。

代码示例:

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

public class LocalDateDemo {
    
    
    public static void main(String[] args) {
    
    
        // 1. 获取当前日期
        LocalDate today = LocalDate.now();
        System.out.println("今天的日期: " + today);

        // 2. 创建指定的日期
        LocalDate birthday = LocalDate.of(2000, Month.JANUARY, 1);
        System.out.println("指定的日期: " + birthday);

        // 3. 获取日期的各个部分
        int year = birthday.getYear();
        int month = birthday.getMonthValue();
        int dayOfMonth = birthday.getDayOfMonth();
        DayOfWeek dayOfWeek = birthday.getDayOfWeek();
        System.out.println("年份: " + year + ", 月份: " + month + ", 日: " + dayOfMonth + ", 星期: " + dayOfWeek);

        // 4. 比较两个日期
        boolean isBefore = birthday.isBefore(today);
        System.out.println("生日是否在今天之前: " + isBefore);

        // 5. 修改日期
        LocalDate modifiedDate = birthday.withYear(2023);
        System.out.println("修改后的日期: " + modifiedDate);
    }
}

解释:

  • LocalDate.now() 获取当前日期。
  • LocalDate.of() 创建指定的日期对象。
  • getYear(), getMonthValue() 等方法可以获取日期的各个部分。
  • isBefore()isAfter() 用于比较两个日期的先后。
  • withXxx() 方法用于修改日期。

4.6 LocalTime 时、分、秒

LocalTime 类表示时间对象,只包含 时、分、秒,不包含日期信息。这类对象通常用于表示一天中的某个时间点,比如会议时间、闹钟时间等。

常见的用法:

  1. 获取当前时间。
  2. 创建指定的时间对象。
  3. 修改时间或进行时间比较。

代码示例:

import java.time.LocalTime;

public class LocalTimeDemo {
    
    
    public static void main(String[] args) {
    
    
        // 1. 获取当前时间
        LocalTime now = LocalTime.now();
        System.out.println("当前时间: " + now);

        // 2. 创建指定的时间
        LocalTime meetingTime = LocalTime.of(14, 30);
        System.out.println("会议时间: " + meetingTime);

        // 3. 获取时间的各个部分
        int hour = meetingTime.getHour();
        int minute = meetingTime.getMinute();
        int second = meetingTime.getSecond();
        System.out.println("时: " + hour + ", 分: " + minute + ", 秒: " + second);

        // 4. 比较两个时间
        boolean isBefore = meetingTime.isBefore(now);
        System.out.println("会议时间是否在当前时间之前: " + isBefore);

        // 5. 修改时间
        LocalTime newTime = meetingTime.plusHours(2);
        System.out.println("延后2小时后的会议时间: " + newTime);
    }
}

解释:

  • LocalTime.now() 获取当前时间。
  • LocalTime.of() 创建指定的时间对象。
  • getHour(), getMinute(), getSecond() 分别获取时间的各个部分。
  • isBefore() 用于比较两个时间的先后。
  • plusXxx() 方法用于增加时间。

4.7 LocalDateTime 年、月、日、时、分、秒

LocalDateTime 类包含了日期和时间信息,结合了 LocalDateLocalTime 的功能,表示精确到秒的日期时间对象。

常见的用法:

  1. 获取当前日期时间。
  2. 创建指定的日期时间对象。
  3. 进行日期时间的修改或比较。

代码示例:

import java.time.LocalDateTime;

public class LocalDateTimeDemo {
    
    
    public static void main(String[] args) {
    
    
        // 1. 获取当前日期时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println("当前日期时间: " + now);

        // 2. 创建指定的日期时间
        LocalDateTime meetingDateTime = LocalDateTime.of(2023, 10, 1, 14, 30);
        System.out.println("会议日期时间: " + meetingDateTime);

        // 3. 获取日期时间的各个部分
        int year = meetingDateTime.getYear();
        int month = meetingDateTime.getMonthValue();
        int day = meetingDateTime.getDayOfMonth();
        int hour = meetingDateTime.getHour();
        int minute = meetingDateTime.getMinute();
        System.out.println("年: " + year + ", 月: " + month + ", 日: " + day + ", 时: " + hour + ", 分: " + minute);

        // 4. 修改日期时间
        LocalDateTime modifiedDateTime = meetingDateTime.plusDays(5);
        System.out.println("5天后的日期时间: " + modifiedDateTime);
    }
}

解释:

  • LocalDateTime.now() 获取当前日期和时间。
  • LocalDateTime.of() 创建指定的日期时间对象。
  • getYear(), getMonthValue() 等方法获取日期时间的各个部分。
  • plusXxx() 用于增加日期或时间。

4.8 Duration 时间间隔(秒,纳秒)

Duration 类用于表示时间的间隔,通常用于两个时间点之间的间隔,精确到秒和纳秒。

常见的用法:

  1. 计算两个 LocalDateTime 之间的时间差。
  2. 将时间差转换为天、小时、分钟等单位。

代码示例:

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

public class DurationDemo {
    
    
    public static void main(String[] args) {
    
    
        // 1. 当前时间
        LocalDateTime now = LocalDateTime.now();

        // 2. 过去的一个时间点
        LocalDateTime past = LocalDateTime.of(2020, 1, 1, 0, 0, 0);

        // 3. 计算时间间隔
        Duration duration = Duration.between(past, now);
        System.out.println("相差的时间间隔: " + duration);

        // 4. 获取相差的天、小时、分钟
        System.out.println("相差的天数: " + duration.toDays());
        System.out.println("相差的小时数: " + duration.toHours());
        System.out.println("相差的分钟数: " + duration.toMinutes());
    }
}

解释:

  • Duration.between() 计算两个 LocalDateTime 之间的间隔。
  • toDays(), toHours(), toMinutes() 等方法用于将时间差转换为不同的单位。

4.9 Period 时间间隔(年,月,日)

Period 类用于表示日期的间隔,通常用于两个日期之间的年、月、日差异。例如,可以计算两个生日之间相差的年数、月数或天数。

常见的用法:

  1. 计算两个 LocalDate 之间的日期差异。
  2. 获取相差的年数、月数、天数。

代码示例:

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

public class PeriodDemo {
    
    
    public static void main(String[] args) {
    
    
        // 1. 获取当前日期
        LocalDate today = LocalDate.now();
        
        // 2. 指定的日期(生日)
        LocalDate birthDate = LocalDate.of(2000, 1, 1);
        
        // 3. 计算日期之间的差异
        Period period = Period.between(birthDate, today);
        System.out.println("相差的时间间隔: " + period);
        
        // 4. 获取相差的年数、月数、天数
        int years = period.getYears();
        int months = period.getMonths();
        int days = period.getDays();
        
        System.out.println("相差的年数: " + years);
        System.out.println("相差的月数: " + months);
        System.out.println("相差的天数: " + days);
        
        // 5. 获取总的相差月份
        System.out.println("相差的总月数: " + period.toTotalMonths());
    }
}

解释:

  • Period.between() 计算两个 LocalDate 之间的年、月、日的差异。
  • getYears(), getMonths(), getDays() 分别获取日期差异中的年数、月数、天数。
  • toTotalMonths() 将日期差异转换为总的月份数。

4.10 ChronoUnit 时间间隔(所有单位)

ChronoUnit 是一个枚举类,它提供了用于测量时间间隔的标准单位,例如年、月、日、小时、分钟等。它的优点在于可以支持非常多的时间单位,从年到秒甚至到纳秒,适用于对两个时间点的精确计算。

常见的用法:

  1. 计算两个时间点之间的差异。
  2. 使用不同的时间单位(年、月、日、小时、分钟等)进行间隔计算。

代码示例:

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

public class ChronoUnitDemo {
    
    
    public static void main(String[] args) {
    
    
        // 1. 当前时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println("当前时间: " + now);
        
        // 2. 指定的时间(生日时间)
        LocalDateTime birthDate = LocalDateTime.of(2000, 1, 1, 0, 0, 0);
        System.out.println("生日时间: " + birthDate);
        
        // 3. 计算时间差异(不同单位)
        System.out.println("相差的年数: " + ChronoUnit.YEARS.between(birthDate, now));
        System.out.println("相差的月数: " + ChronoUnit.MONTHS.between(birthDate, now));
        System.out.println("相差的周数: " + ChronoUnit.WEEKS.between(birthDate, now));
        System.out.println("相差的天数: " + ChronoUnit.DAYS.between(birthDate, now));
        System.out.println("相差的小时数: " + ChronoUnit.HOURS.between(birthDate, now));
        System.out.println("相差的分钟数: " + ChronoUnit.MINUTES.between(birthDate, now));
        System.out.println("相差的秒数: " + ChronoUnit.SECONDS.between(birthDate, now));
        System.out.println("相差的毫秒数: " + ChronoUnit.MILLIS.between(birthDate, now));
        System.out.println("相差的微秒数: " + ChronoUnit.MICROS.between(birthDate, now));
        System.out.println("相差的纳秒数: " + ChronoUnit.NANOS.between(birthDate, now));
        System.out.println("相差的十年数: " + ChronoUnit.DECADES.between(birthDate, now));
        System.out.println("相差的世纪数: " + ChronoUnit.CENTURIES.between(birthDate, now));
    }
}

解释:

  • ChronoUnit.YEARS.between() 计算两个时间点之间的年数差异。
  • ChronoUnit.MONTHS.between() 计算两个时间点之间的月数差异。
  • ChronoUnit.WEEKS.between() 计算两个时间点之间的周数差异。
  • ChronoUnit.DAYS.between() 计算两个时间点之间的天数差异。
  • ChronoUnit.HOURS.between() 计算两个时间点之间的小时数差异,依次类推。

猜你喜欢

转载自blog.csdn.net/PQ781826/article/details/143268846