第一章 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日
}
}
补充说明:在日期格式转换过程中,要确保
SimpleDateFormat
的pattern
与输入字符串的格式完全一致。否则会抛出ParseException
异常。
2.5 SimpleDateFormat
的线程安全问题
SimpleDateFormat
在多线程环境下并不是线程安全的。为了避免数据不一致的问题,通常有两种解决方案:
- 每个线程使用独立的
SimpleDateFormat
实例。 - 使用
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,它解决了旧版 Date
和 Calendar
类的缺陷,并且更加直观、简洁和线程安全。这些类位于 java.time
包中。接下来我们会逐一讲解主要的时间相关类及其功能。
JDK8 时间类名 | 功能描述 |
---|---|
ZoneId | 时区 |
Instant | 时间戳 |
ZonedDateTime | 带时区的时间 |
DateTimeFormatter | 时间格式化与解析 |
LocalDate | 仅包含日期(年、月、日) |
LocalTime | 仅包含时间(时、分、秒) |
LocalDateTime | 包含日期和时间(年、月、日、时、分、秒) |
Duration | 时间间隔(秒、纳秒) |
Period | 时间间隔(年、月、日) |
ChronoUnit | 时间间隔(不同单位) |
4.1 ZoneId 时区类
ZoneId
用于表示一个时区,它可以帮助我们在全球不同的时区之间进行时间计算和转换。
常见的用法:
- 获取系统默认时区。
- 获取所有支持的时区。
- 创建一个特定的时区。
代码示例:
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
类,但功能更强大。
常见的用法:
- 获取当前的时间戳。
- 从秒或毫秒值创建
Instant
对象。 - 比较两个时间戳之间的先后。
代码示例:
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
是一个包含时区的日期时间类,适用于需要处理带有时区的时间的场景,比如全球时区转换。
常见的用法:
- 获取当前的带时区的时间。
- 指定时间和时区,创建
ZonedDateTime
对象。 - 修改
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
类用于格式化和解析日期、时间。它可以将 LocalDateTime
、LocalDate
或 LocalTime
格式化为字符串,也可以从特定格式的字符串中解析出日期或时间对象。
常见的用法:
- 格式化日期和时间对象为字符串。
- 从字符串解析出日期和时间对象。
代码示例:
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
类表示日期对象,只包含 年、月、日,不包含时间信息。这类对象通常用于表示一个完整的日期,比如生日、纪念日等。
常见的用法:
- 获取当前日期。
- 获取指定的日期对象。
- 修改日期或进行日期比较。
代码示例:
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
类表示时间对象,只包含 时、分、秒,不包含日期信息。这类对象通常用于表示一天中的某个时间点,比如会议时间、闹钟时间等。
常见的用法:
- 获取当前时间。
- 创建指定的时间对象。
- 修改时间或进行时间比较。
代码示例:
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
类包含了日期和时间信息,结合了 LocalDate
和 LocalTime
的功能,表示精确到秒的日期时间对象。
常见的用法:
- 获取当前日期时间。
- 创建指定的日期时间对象。
- 进行日期时间的修改或比较。
代码示例:
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
类用于表示时间的间隔,通常用于两个时间点之间的间隔,精确到秒和纳秒。
常见的用法:
- 计算两个
LocalDateTime
之间的时间差。 - 将时间差转换为天、小时、分钟等单位。
代码示例:
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
类用于表示日期的间隔,通常用于两个日期之间的年、月、日差异。例如,可以计算两个生日之间相差的年数、月数或天数。
常见的用法:
- 计算两个
LocalDate
之间的日期差异。 - 获取相差的年数、月数、天数。
代码示例:
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
是一个枚举类,它提供了用于测量时间间隔的标准单位,例如年、月、日、小时、分钟等。它的优点在于可以支持非常多的时间单位,从年到秒甚至到纳秒,适用于对两个时间点的精确计算。
常见的用法:
- 计算两个时间点之间的差异。
- 使用不同的时间单位(年、月、日、小时、分钟等)进行间隔计算。
代码示例:
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()
计算两个时间点之间的小时数差异,依次类推。