java.time:如何验证日历周的有效性
如何验证ISO-8601日历系统中的有效日历周?
要验证某个基于周的年份对应的日历周是否有效,用Java 8及以后版本自带的java.time库就能轻松实现——它原生支持ISO-8601的周历规则,先明确下核心规则:
基于周的年份的第一周是标准ISO年份中首个以周一为起始且新年至少包含4天的周
实现思路
核心逻辑很简单:尝试用输入的基于周的年份和周数构造对应日期,如果构造成功,且构造出的日期的周年份、周数和输入完全匹配,就说明这个周是有效的;如果构造时抛出异常,或者匹配失败,就判定为无效。
代码示例
import java.time.LocalDate; import java.time.temporal.IsoFields; import java.time.DateTimeException; public class IsoWeekValidator { // 验证指定的基于周的年份和周数是否有效 public static boolean isIsoWeekValid(int weekBasedYear, int weekNumber) { try { // 构造该周的周一(ISO周以周一为每周第一天) LocalDate targetDate = LocalDate.of(weekBasedYear, 1, 1) .with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber) .with(IsoFields.DAY_OF_WEEK, 1); // 双重校验:确保构造出的日期确实属于输入的周年份和周数 return targetDate.get(IsoFields.WEEK_BASED_YEAR) == weekBasedYear && targetDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR) == weekNumber; } catch (DateTimeException e) { // 周数超出范围时会抛出异常,直接返回无效 return false; } } public static void main(String[] args) { // 测试示例 System.out.println(isIsoWeekValid(2018, 53)); // 输出 false,2018年只有52周 System.out.println(isIsoWeekValid(2020, 53)); // 输出 true,2020年第53周有效(覆盖2020.12.28-2021.1.3) } }
代码说明
- 构造日期:通过
with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber)定位到目标周,再指定到周一开始的日期,确保我们定位的是完整周的起始点。 - 异常捕获:如果输入的周数超出该年份的有效范围(比如2018年的第53周),调用
with方法时会抛出DateTimeException,此时直接返回false。 - 双重校验:有些极端情况(比如输入2019年第53周),构造出来的日期会自动调整到2020年的第1周,这时候虽然不会抛异常,但周年份已经和输入不符,所以必须校验这两个值,确保是对应年份的有效周。
补充说明
像2020年第53周这种跨自然年的情况是完全符合ISO规则的:这个周里有4天属于2020年,满足“新年至少包含4天”的反向逻辑(即该周的大部分天数属于2020年),所以被归为2020年的基于周的年份的第53周。
内容的提问来源于stack exchange,提问作者olivmir
相关产品推荐
相关产品推荐

