如何在Kotlin/Java中实现符合规范的广播日历周数计算
解决广播日历周数计算问题
核心问题在于WeekFields的周归属规则与广播日历不符:广播日历要求包含当年1月1日的周为当年第1周,跨年度的周只要包含下一年1月1日,就属于下一年第1周;而WeekFields.of(DayOfWeek.MONDAY, 1)的规则是“周内至少1天在当年则归属于当年”,导致年末跨周的日期被算入当年的最后一周(如2022年12月31日被算为2022年第53周),不符合广播日历规范。
自定义实现方案
我们可以通过以下逻辑手动实现广播日历的周数计算:
- 确定当前日期所在的广播周(周一为起始,周日为结束)
- 判断该周是否包含下一年的1月1日:若是,归属于下一年第1周
- 判断该周是否包含当年的1月1日:若是,归属于当年第1周
- 否则,计算该周与当年第一周的间隔,得到周数
Kotlin 代码实现
import java.time.LocalDate import java.time.DayOfWeek import java.time.temporal.ChronoUnit import java.time.temporal.TemporalAdjusters fun getBroadcastWeek(date: LocalDate): Pair<Int, Int> { // 获取当前日期所在广播周的周一(起始日)和周日(结束日) val weekStart = date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)) val weekEnd = weekStart.plusDays(6) val currentYear = date.year val nextYearJan1 = LocalDate.of(currentYear + 1, 1, 1) val currentYearJan1 = LocalDate.of(currentYear, 1, 1) // 情况1:当前周包含下一年1月1日,属于下一年第1周 if (weekEnd == nextYearJan1) { return Pair(currentYear + 1, 1) } // 情况2:当前周包含当年1月1日,属于当年第1周 if (weekStart <= currentYearJan1 && currentYearJan1 <= weekEnd) { return Pair(currentYear, 1) } // 情况3:计算当前周是当年的第几周 val firstWeekStart = currentYearJan1.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)) val weeksDiff = ChronoUnit.WEEKS.between(firstWeekStart, weekStart).toInt() return Pair(currentYear, weeksDiff + 1) } // 测试示例 fun main() { val lastDay2022 = LocalDate.of(2022, 12, 31) val (year1, week1) = getBroadcastWeek(lastDay2022) println("2022-12-31: $year1 第$week1周") // 输出:2023 第1周 val firstDay2023 = LocalDate.of(2023, 1, 1) val (year2, week2) = getBroadcastWeek(firstDay2023) println("2023-01-01: $year2 第$week2周") // 输出:2023 第1周 val dec252022 = LocalDate.of(2022, 12, 25) val (year3, week3) = getBroadcastWeek(dec252022) println("2022-12-25: $year3 第$week3周") // 输出:2022 第52周 val march12022 = LocalDate.of(2022, 3, 1) val (year4, week4) = getBroadcastWeek(march12022) println("2022-03-01: $year4 第$week4周") // 输出:2022 第10周 }
验证结果
- 2022年12月31日:属于2023年第1周(符合广播日历规范)
- 2023年1月1日:属于2023年第1周(符合规范)
- 2022年12月25日:属于2022年第52周(符合规范)
- 2022年3月1日:周数保持正确(与原实现一致)
内容的提问来源于stack exchange,提问作者uzilan
相关产品推荐
相关产品推荐

