424. Java 日期时间 API - 专注于日期的类
在 Java 8 的 Date-Time API 里,有一组类专门用来处理 日期,而不是时间或者时区。它们是:
- LocalDate:完整的年月日
- YearMonth:某一年的某个月
- MonthDay:某一年的某一天(忽略年份)
- Year:单独的一年
这些类的共同点是:只关心日期,不涉及时分秒,也不涉及时区。非常适合处理生日、节日、账单日期等场景。
✅ LocalDate —— 具体的一天
- 表示:
年-月-日(基于 ISO-8601 日历系统) - 场景:适合表示生日、结婚纪念日、节日等。
🔹 示例 1:创建 LocalDate
LocalDate date = LocalDate.of(2000, Month.NOVEMBER, 20);
System.out.println("Date: " + date);
👉 输出:
Date: 2000-11-20
🔹 示例 2:获取星期几
DayOfWeek dow = LocalDate.of(2012, Month.JULY, 9).getDayOfWeek();
System.out.println(dow);
👉 输出:
MONDAY
也就是说,2012-07-09 是星期一。
🔹 示例 3:查找下一个星期三
这里要用到 TemporalAdjuster 辅助类。
LocalDate date = LocalDate.of(2000, Month.NOVEMBER, 20);
LocalDate nextWed = date.with(TemporalAdjusters.next(DayOfWeek.WEDNESDAY));
System.out.printf("For the date of %s, the next Wednesday is %s.%n",
date, nextWed);
👉 输出:
For the date of 2000-11-20, the next Wednesday is 2000-11-22.
💡 场景举例: 比如你有一个“每周三开会”的日程,给定某天,就能快速算出下一个周三的日期。
✅ YearMonth —— 某年某月
- 表示:某个具体的 年 + 月。
- 场景:比如账单日、工资月份、统计数据的月份。
🔹 示例:判断某月有多少天
YearMonth date1 = YearMonth.now();
System.out.printf("%s: %d%n", date1, date1.lengthOfMonth());
YearMonth date2 = YearMonth.of(2010, Month.FEBRUARY);
System.out.printf("%s: %d%n", date2, date2.lengthOfMonth());
YearMonth date3 = YearMonth.of(2012, Month.FEBRUARY);
System.out.printf("%s: %d%n", date3, date3.lengthOfMonth());
👉 输出:
2025-09: 30
2010-02: 28
2012-02: 29
💡 可以用来判断闰年二月的天数。
✅ MonthDay —— 某月某日(忽略年份)
- 表示:一个日期,不包含年份。
- 场景:生日、节日(例如情人节 2 月 14 日、新年 1 月 1 日)。
🔹 示例:判断闰年日期是否有效
MonthDay date = MonthDay.of(Month.FEBRUARY, 29);
boolean validLeapYear = date.isValidYear(2010);
System.out.println(validLeapYear);
👉 输出:
false
说明:2010 年不是闰年,所以 2010-02-29 不存在。
💡 这个很适合做生日提醒:如果有人生日是 2 月 29 日,非闰年就要特殊处理。
✅ Year —— 单独的一年
- 表示:年份。
- 场景:年份统计、财务年度、学年等。
🔹 示例:判断是否闰年
boolean isLeap = Year.of(2012).isLeap();
System.out.println(isLeap);
👉 输出:
true
💡 适合做年份验证,比如日历应用、学期安排。
🎯 小结
- LocalDate:完整年月日,适合日常日期计算。
- YearMonth:特定年和月,适合账单、工资月份。
- MonthDay:某月某日,适合生日、节日。
- Year:单独的年份,适合年份校验。
👉 它们都不涉及时分秒,也不涉及时区。 👉 非常适合处理“日期为主”的业务逻辑。