You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:50:39