Java LocalDate 类
LocalDate 是 Java 8 中引入的一个不可变日期类,属于 java.time
包的一部分。
LocalDate 表示不带时区的日期(年-月-日),例如 "2023-05-15"。LocalDate 不包含时间和时区信息,非常适合处理生日、节假日等只需要日期的场景。
LocalDate 的主要特点
1. 不可变性
LocalDate 实例是不可变的,任何修改操作都会返回一个新的 LocalDate 对象,而不是修改原有对象。
2. 线程安全
由于不可变性,LocalDate 是线程安全的,可以在多线程环境中安全使用。
3. ISO-8601 标准
LocalDate 遵循 ISO-8601 日历系统,这是现代日期和时间表示的国际标准。
创建 LocalDate 对象
1. 获取当前日期
LocalDate today = LocalDate.now(); System.out.println("今天的日期: " + today);
2. 使用特定日期创建
LocalDate specificDate = LocalDate.of(2023, Month.MAY, 15); // 或者 LocalDate specificDate2 = LocalDate.of(2023, 5, 15);
3. 从字符串解析
LocalDate parsedDate = LocalDate.parse("2023-05-15");
常用操作方法
1. 获取日期信息
实例
LocalDate date = LocalDate.of(2023, 5, 15);
int year = date.getYear(); // 2023
Month month = date.getMonth(); // MAY
int day = date.getDayOfMonth(); // 15
DayOfWeek dow = date.getDayOfWeek(); // MONDAY
int len = date.lengthOfMonth(); // 31 (5月的天数)
boolean leap = date.isLeapYear(); // false (2023不是闰年)
int year = date.getYear(); // 2023
Month month = date.getMonth(); // MAY
int day = date.getDayOfMonth(); // 15
DayOfWeek dow = date.getDayOfWeek(); // MONDAY
int len = date.lengthOfMonth(); // 31 (5月的天数)
boolean leap = date.isLeapYear(); // false (2023不是闰年)
2. 日期加减
实例
LocalDate tomorrow = today.plusDays(1);
LocalDate nextWeek = today.plusWeeks(1);
LocalDate nextMonth = today.plusMonths(1);
LocalDate nextYear = today.plusYears(1);
LocalDate yesterday = today.minusDays(1);
LocalDate nextWeek = today.plusWeeks(1);
LocalDate nextMonth = today.plusMonths(1);
LocalDate nextYear = today.plusYears(1);
LocalDate yesterday = today.minusDays(1);
3. 日期比较
实例
LocalDate date1 = LocalDate.of(2023, 5, 15);
LocalDate date2 = LocalDate.of(2023, 6, 20);
boolean isBefore = date1.isBefore(date2); // true
boolean isAfter = date1.isAfter(date2); // false
boolean isEqual = date1.isEqual(date2); // false
LocalDate date2 = LocalDate.of(2023, 6, 20);
boolean isBefore = date1.isBefore(date2); // true
boolean isAfter = date1.isAfter(date2); // false
boolean isEqual = date1.isEqual(date2); // false
4. 调整日期
实例
LocalDate date = LocalDate.of(2023, 5, 15);
LocalDate firstDayOfMonth = date.withDayOfMonth(1);
LocalDate lastDayOfYear = date.with(TemporalAdjusters.lastDayOfYear());
LocalDate firstDayOfMonth = date.withDayOfMonth(1);
LocalDate lastDayOfYear = date.with(TemporalAdjusters.lastDayOfYear());
格式化与解析
1. 格式化日期
实例
LocalDate date = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String formattedDate = date.format(formatter);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String formattedDate = date.format(formatter);
2. 解析字符串为日期
实例
String dateStr = "2023/05/15";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date = LocalDate.parse(dateStr, formatter);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date = LocalDate.parse(dateStr, formatter);
实际应用示例
1. 计算两个日期之间的天数
实例
LocalDate startDate = LocalDate.of(2023, 5, 1);
LocalDate endDate = LocalDate.of(2023, 5, 15);
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
System.out.println("天数差: " + daysBetween);
LocalDate endDate = LocalDate.of(2023, 5, 15);
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
System.out.println("天数差: " + daysBetween);
2. 检查日期是否在范围内
实例
LocalDate dateToCheck = LocalDate.of(2023, 5, 10);
LocalDate startDate = LocalDate.of(2023, 5, 1);
LocalDate endDate = LocalDate.of(2023, 5, 31);
if (dateToCheck.isAfter(startDate) && dateToCheck.isBefore(endDate)) {
System.out.println("日期在范围内");
}
LocalDate startDate = LocalDate.of(2023, 5, 1);
LocalDate endDate = LocalDate.of(2023, 5, 31);
if (dateToCheck.isAfter(startDate) && dateToCheck.isBefore(endDate)) {
System.out.println("日期在范围内");
}
3. 获取某月的所有日期
实例
LocalDate date = LocalDate.of(2023, 5, 1);
int daysInMonth = date.lengthOfMonth();
for (int i = 1; i <= daysInMonth; i++) {
System.out.println(date.withDayOfMonth(i));
}
int daysInMonth = date.lengthOfMonth();
for (int i = 1; i <= daysInMonth; i++) {
System.out.println(date.withDayOfMonth(i));
}
综合实例
实例
import java.time.LocalDate;
import java.time.Month;
import java.time.DayOfWeek;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Locale;
public class LocalDateDemo {
public static void main(String[] args) {
// 1. 创建 LocalDate 实例
System.out.println("=== 创建 LocalDate 实例 ===");
LocalDate today = LocalDate.now();
LocalDate specificDate = LocalDate.of(2023, Month.JULY, 15);
LocalDate parsedDate = LocalDate.parse("2023-08-20");
System.out.println("当前日期: " + today);
System.out.println("特定日期: " + specificDate);
System.out.println("解析日期: " + parsedDate);
// 2. 获取日期信息
System.out.println("\n=== 获取日期信息 ===");
System.out.println("年: " + today.getYear());
System.out.println("月: " + today.getMonth() + " (" + today.getMonthValue() + ")");
System.out.println("日: " + today.getDayOfMonth());
System.out.println("星期: " + today.getDayOfWeek());
System.out.println("一年中的第几天: " + today.getDayOfYear());
System.out.println("月份天数: " + today.lengthOfMonth());
System.out.println("年份天数: " + today.lengthOfYear());
System.out.println("是否闰年: " + today.isLeapYear());
// 3. 日期计算
System.out.println("\n=== 日期计算 ===");
System.out.println("加5天: " + today.plusDays(5));
System.out.println("加2周: " + today.plusWeeks(2));
System.out.println("加3个月: " + today.plusMonths(3));
System.out.println("减1年: " + today.minusYears(1));
System.out.println("下个月的第一天: " + today.plusMonths(1).withDayOfMonth(1));
System.out.println("本月的最后一天: " + today.withDayOfMonth(today.lengthOfMonth()));
// 4. 日期比较
System.out.println("\n=== 日期比较 ===");
LocalDate date1 = LocalDate.of(2023, 6, 15);
LocalDate date2 = LocalDate.of(2023, 6, 20);
System.out.println(date1 + " 在 " + date2 + " 之前? " + date1.isBefore(date2));
System.out.println(date1 + " 在 " + date2 + " 之后? " + date1.isAfter(date2));
System.out.println(date1 + " 等于 " + date2 + "? " + date1.isEqual(date2));
// 5. 计算日期差
System.out.println("\n=== 计算日期差 ===");
LocalDate startDate = LocalDate.of(2023, 1, 1);
LocalDate endDate = LocalDate.of(2023, 12, 31);
System.out.println("两个日期之间的天数: " + ChronoUnit.DAYS.between(startDate, endDate));
System.out.println("两个日期之间的月数: " + ChronoUnit.MONTHS.between(startDate, endDate));
System.out.println("两个日期之间的年数: " + ChronoUnit.YEARS.between(startDate, endDate));
// 6. 日期格式化
System.out.println("\n=== 日期格式化 ===");
DateTimeFormatter basicFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 EEEE", Locale.CHINA);
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy", Locale.US);
System.out.println("基本格式: " + today.format(basicFormatter));
System.out.println("中文格式: " + today.format(chineseFormatter));
System.out.println("英文格式: " + today.format(customFormatter));
// 7. 其他实用方法
System.out.println("\n=== 其他实用方法 ===");
System.out.println("调整到下个星期一: " + today.with(DayOfWeek.MONDAY));
System.out.println("是否是周末: " +
(today.getDayOfWeek() == DayOfWeek.SATURDAY || today.getDayOfWeek() == DayOfWeek.SUNDAY));
// 8. 日期范围迭代
System.out.println("\n=== 日期范围迭代 ===");
System.out.println("接下来7天的日期:");
today.datesUntil(today.plusDays(7))
.forEach(System.out::println);
}
}
import java.time.Month;
import java.time.DayOfWeek;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Locale;
public class LocalDateDemo {
public static void main(String[] args) {
// 1. 创建 LocalDate 实例
System.out.println("=== 创建 LocalDate 实例 ===");
LocalDate today = LocalDate.now();
LocalDate specificDate = LocalDate.of(2023, Month.JULY, 15);
LocalDate parsedDate = LocalDate.parse("2023-08-20");
System.out.println("当前日期: " + today);
System.out.println("特定日期: " + specificDate);
System.out.println("解析日期: " + parsedDate);
// 2. 获取日期信息
System.out.println("\n=== 获取日期信息 ===");
System.out.println("年: " + today.getYear());
System.out.println("月: " + today.getMonth() + " (" + today.getMonthValue() + ")");
System.out.println("日: " + today.getDayOfMonth());
System.out.println("星期: " + today.getDayOfWeek());
System.out.println("一年中的第几天: " + today.getDayOfYear());
System.out.println("月份天数: " + today.lengthOfMonth());
System.out.println("年份天数: " + today.lengthOfYear());
System.out.println("是否闰年: " + today.isLeapYear());
// 3. 日期计算
System.out.println("\n=== 日期计算 ===");
System.out.println("加5天: " + today.plusDays(5));
System.out.println("加2周: " + today.plusWeeks(2));
System.out.println("加3个月: " + today.plusMonths(3));
System.out.println("减1年: " + today.minusYears(1));
System.out.println("下个月的第一天: " + today.plusMonths(1).withDayOfMonth(1));
System.out.println("本月的最后一天: " + today.withDayOfMonth(today.lengthOfMonth()));
// 4. 日期比较
System.out.println("\n=== 日期比较 ===");
LocalDate date1 = LocalDate.of(2023, 6, 15);
LocalDate date2 = LocalDate.of(2023, 6, 20);
System.out.println(date1 + " 在 " + date2 + " 之前? " + date1.isBefore(date2));
System.out.println(date1 + " 在 " + date2 + " 之后? " + date1.isAfter(date2));
System.out.println(date1 + " 等于 " + date2 + "? " + date1.isEqual(date2));
// 5. 计算日期差
System.out.println("\n=== 计算日期差 ===");
LocalDate startDate = LocalDate.of(2023, 1, 1);
LocalDate endDate = LocalDate.of(2023, 12, 31);
System.out.println("两个日期之间的天数: " + ChronoUnit.DAYS.between(startDate, endDate));
System.out.println("两个日期之间的月数: " + ChronoUnit.MONTHS.between(startDate, endDate));
System.out.println("两个日期之间的年数: " + ChronoUnit.YEARS.between(startDate, endDate));
// 6. 日期格式化
System.out.println("\n=== 日期格式化 ===");
DateTimeFormatter basicFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 EEEE", Locale.CHINA);
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy", Locale.US);
System.out.println("基本格式: " + today.format(basicFormatter));
System.out.println("中文格式: " + today.format(chineseFormatter));
System.out.println("英文格式: " + today.format(customFormatter));
// 7. 其他实用方法
System.out.println("\n=== 其他实用方法 ===");
System.out.println("调整到下个星期一: " + today.with(DayOfWeek.MONDAY));
System.out.println("是否是周末: " +
(today.getDayOfWeek() == DayOfWeek.SATURDAY || today.getDayOfWeek() == DayOfWeek.SUNDAY));
// 8. 日期范围迭代
System.out.println("\n=== 日期范围迭代 ===");
System.out.println("接下来7天的日期:");
today.datesUntil(today.plusDays(7))
.forEach(System.out::println);
}
}
输出结果类似如下:
=== 创建 LocalDate 实例 === 当前日期: 2023-06-15 特定日期: 2023-07-15 解析日期: 2023-08-20 === 获取日期信息 === 年: 2023 月: JUNE (6) 日: 15 星期: THURSDAY 一年中的第几天: 166 月份天数: 30 年份天数: 365 是否闰年: false === 日期计算 === 加5天: 2023-06-20 加2周: 2023-06-29 加3个月: 2023-09-15 减1年: 2022-06-15 下个月的第一天: 2023-07-01 本月的最后一天: 2023-06-30 === 日期比较 === 2023-06-15 在 2023-06-20 之前? true 2023-06-15 在 2023-06-20 之后? false 2023-06-15 等于 2023-06-20? false === 计算日期差 === 两个日期之间的天数: 364 两个日期之间的月数: 11 两个日期之间的年数: 0 === 日期格式化 === 基本格式: 2023/06/15 中文格式: 2023年06月15日 星期四 英文格式: Jun 15, 2023 === 其他实用方法 === 调整到下个星期一: 2023-06-19 是否是周末: false === 日期范围迭代 === 接下来7天的日期: 2023-06-15 2023-06-16 2023-06-17 2023-06-18 2023-06-19 2023-06-20 2023-06-21
总结
LocalDate 类是 Java 8 日期时间 API 的重要组成部分,它提供了丰富的方法来处理日期相关的操作。相比旧的 Date 和 Calendar 类,LocalDate 更加直观、易用且线程安全。掌握 LocalDate 的使用可以大大提高日期处理的效率和代码的可读性。
以下是其常用方法:
静态工厂方法
方法 | 描述 | 示例 |
---|---|---|
static LocalDate now() |
获取当前日期 | LocalDate.now() |
static LocalDate of(int year, int month, int dayOfMonth) |
指定年月日创建 | LocalDate.of(2023, 6, 15) |
static LocalDate of(int year, Month month, int dayOfMonth) |
指定年月日创建(使用Month枚举) | LocalDate.of(2023, Month.JUNE, 15) |
static LocalDate parse(CharSequence text) |
从字符串解析(ISO格式:yyyy-MM-dd) | LocalDate.parse("2023-06-15") |
static LocalDate parse(CharSequence text, DateTimeFormatter formatter) |
使用指定格式解析 | LocalDate.parse("15/06/2023", DateTimeFormatter.ofPattern("dd/MM/yyyy")) |
获取日期信息
方法 | 描述 | 示例 |
---|---|---|
int getYear() |
获取年份 | 2023 |
Month getMonth() |
获取月份(Month枚举) | Month.JUNE |
int getMonthValue() |
获取月份值(1-12) | 6 |
int getDayOfMonth() |
获取月中的天数 | 15 |
int getDayOfYear() |
获取年中的天数 | 166 |
DayOfWeek getDayOfWeek() |
获取星期几(DayOfWeek枚举) | DayOfWeek.THURSDAY |
int lengthOfMonth() |
返回月份的天数 | 30 |
int lengthOfYear() |
返回年份的天数(365或366) | 365 |
boolean isLeapYear() |
判断是否是闰年 | false |
日期操作
方法 | 描述 | 示例 |
---|---|---|
LocalDate plusDays(long days) |
添加天数 | date.plusDays(5) |
LocalDate plusWeeks(long weeks) |
添加周数 | date.plusWeeks(2) |
LocalDate plusMonths(long months) |
添加月数 | date.plusMonths(3) |
LocalDate plusYears(long years) |
添加年数 | date.plusYears(1) |
LocalDate minusDays(long days) |
减去天数 | date.minusDays(5) |
LocalDate minusWeeks(long weeks) |
减去周数 | date.minusWeeks(2) |
LocalDate minusMonths(long months) |
减去月数 | date.minusMonths(3) |
LocalDate minusYears(long years) |
减去年数 | date.minusYears(1) |
LocalDate withDayOfMonth(int dayOfMonth) |
修改月中的天数 | date.withDayOfMonth(1) |
LocalDate withDayOfYear(int dayOfYear) |
修改年中的天数 | date.withDayOfYear(100) |
LocalDate withMonth(int month) |
修改月份 | date.withMonth(12) |
LocalDate withYear(int year) |
修改年份 | date.withYear(2024) |
日期比较
方法 | 描述 | 示例 |
---|---|---|
boolean isAfter(ChronoLocalDate other) |
是否在指定日期之后 | date1.isAfter(date2) |
boolean isBefore(ChronoLocalDate other) |
是否在指定日期之前 | date1.isBefore(date2) |
boolean isEqual(ChronoLocalDate other) |
是否等于指定日期 | date1.isEqual(date2) |
long until(ChronoLocalDate endDate, ChronoUnit unit) |
计算两个日期之间的时间量 | date1.until(date2, ChronoUnit.DAYS) |
格式化与转换
方法 | 描述 | 示例 |
---|---|---|
String format(DateTimeFormatter formatter) |
格式化为字符串 | date.format(DateTimeFormatter.ISO_DATE) |
String toString() |
转换为ISO格式字符串(yyyy-MM-dd) | "2023-06-15" |
long toEpochDay() |
转换为从1970-01-01开始的天数 | 19531 |
LocalDateTime atTime(int hour, int minute) |
转换为LocalDateTime | date.atTime(14, 30) |
LocalDateTime atTime(LocalTime time) |
转换为LocalDateTime | date.atTime(LocalTime.now()) |
其他实用方法
方法 | 描述 | 示例 |
---|---|---|
boolean isSupported(ChronoUnit unit) |
检查是否支持时间单位 | date.isSupported(ChronoUnit.DAYS) |
boolean isSupported(ChronoField field) |
检查是否支持时间字段 | date.isSupported(ChronoField.HOUR_OF_DAY) |
LocalDate with(TemporalAdjuster adjuster) |
使用调整器调整日期 | date.with(TemporalAdjusters.firstDayOfMonth()) |