📐 ISO 8601 周数标准完整指南
全面理解国际周数计算标准
ISO 8601 是国际标准化组织(ISO)制定的日期和时间表示法国际标准。其中的周数系统是全球使用最广泛的周数计算标准,被欧盟、中国、日本和大多数国家采用。
📏 三大核心规则
1
每周从周一开始
ISO 8601规定一周的起始日是星期一(Monday),结束日是星期日(Sunday)。这与美国和加拿大的习惯不同——美国通常认为一周从周日开始。
2
第1周包含该年的第一个星期四
一年的第一周(Week 1)是包含该年第一个星期四的那一周。这个规则等价于:第1周是包含1月4日的那一周,或者是第一个大部分天数(至少4天)在新年里的那一周。
3
一年有52周或53周
一年如果有53周,称为长闰年(Long Year)。判断标准:如果一年的最后一天是星期四,或者一年的最后一天是星期五且是闰年,则这一年有53周。实际上,一个更简单的判断方法是:如果1月1日是星期四(普通年)或星期三/星期四(闰年),则这一年有53周。
🔢 如何计算ISO周数?
计算给定日期所属的ISO周数,可以按照以下步骤:
- 找到该日期所在的星期四(加或减相应的天数)
- 该星期四所属的年份即为ISO年份
- 计算该星期四在该年份中的第几个星期四,即为周数
JavaScript实现:
function getISOWeek(date) {
// Create a copy and shift to Thursday
const d = new Date(Date.UTC(
date.getFullYear(), date.getMonth(), date.getDate()
));
// Set to nearest Thursday: current date + 4 - current day number
// Make Sunday = 7
const dayNum = d.getUTCDay() || 7;
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
// Get first day of year
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
// Calculate full weeks to nearest Thursday
const weekNo = Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
return {
week: weekNo,
year: d.getUTCFullYear()
};
}
// Usage:
console.log(getISOWeek(new Date('2026-06-20')));
// { week: 25, year: 2026 }
Python实现:
from datetime import date
def get_iso_week(d):
"""Return (ISO_year, ISO_week) for a given date."""
return d.isocalendar()[0], d.isocalendar()[1]
# Usage:
print(get_iso_week(date(2026, 6, 20)))
# (2026, 25)
🇺🇸 ISO 8601 vs US周数体系对比
| 特性 | ISO 8601 | US体系 |
|---|---|---|
| 一周起始日 | 周一 | 周日 |
| 第1周的定义 | 包含第一个星期四的周 | 包含1月1日的周 |
| 周数范围 | 1–53 | 1–54(罕见) |
| 使用地区 | 欧洲、中国、日本、大多数国家 | 美国、加拿大 |
| 第1周可能跨年 | 是(如2026年第1周始于2025/12/29) | 不跨年 |
| 官方标准 | ISO 8601:2004 | 无正式国际标准 |
📅 哪些年份有53周?
以下年份有53周(2020–2040):
2020, 2026, 2032, 2037 — 大约每5–6年出现一次。
判断规则:如果一年的1月1日是星期四,或者该年是闰年且1月1日是星期三,则该年有53周。
2026年正好满足第一个条件(1月1日是星期四),因此2026年有53周。
💼 实际应用场景
- 工资计算:53周的年份会导致两周发薪的员工多领一次工资,需要财务提前规划。
- 项目管理(Sprint):Scrum和敏捷团队使用周数来定义Sprint周期。
- 学期规划:欧洲高校普遍使用ISO周数来定义学期和考试周。
- 生产制造:工厂使用周数进行生产排期和质量追溯。
- 物流运输:国际物流单证上需要标注ISO周数。