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

如何通过年份和周数获取对应周一日期(避免依赖1900-01-01)

解决方案:通过年份和周数获取对应周的周一日期

旧查询的问题分析

你当前的查询依赖1900-01-01(一个周一)作为基准,但每年的1月1日不一定是周一,直接按周数偏移会导致起始日偏差。比如2022年1月1日是周六,旧方法计算出的第50周起始日是周六(12月10日),而非你需要的周一(12月12日)。

不依赖固定基准日期的正确写法

以下是主流SQL数据库的实现,完全基于目标年份的日期计算,不依赖1900-01-01:

SQL Server

DECLARE @yearnum INT = 2022, @weeknum INT = 50;

-- 计算当年的第一个周一
DECLARE @FirstMonday DATE = DATEADD(day, 
    CASE DATEPART(weekday, DATEFROMPARTS(@yearnum, 1, 1))
        WHEN 1 THEN 1  -- 1月1日是周日,加1天到周一
        WHEN 2 THEN 0  -- 1月1日本身是周一
        ELSE 2 - DATEPART(weekday, DATEFROMPARTS(@yearnum, 1, 1))
    END,
    DATEFROMPARTS(@yearnum, 1, 1)
);

-- 偏移到目标周的周一
SELECT DATEADD(week, @weeknum - 1, @FirstMonday) AS MondayOfTargetWeek;

如果你的业务遵循ISO周规则(周一为起始,第一周包含当年至少4天),可以用更简洁的写法:

DECLARE @yearnum INT = 2022, @weeknum INT = 50;
SELECT DATEADD(day, 1 - DATEPART(weekday, iso_week_start), iso_week_start) AS MondayOfWeek
FROM (
    SELECT DATEADD(week, @weeknum - 1, DATEFROMPARTS(@yearnum, 1, 4)) AS iso_week_start
) t;

MySQL

如果按“每年第一周为包含1月1日的周,周一为周起始”:

SET @yearnum = 2022, @weeknum = 50;

-- 计算目标周的起始日期,再调整到周一
SELECT DATE_ADD(
    DATE_ADD(MAKEDATE(@yearnum, 1), INTERVAL (@weeknum - 1) WEEK),
    INTERVAL (1 - DAYOFWEEK(DATE_ADD(MAKEDATE(@yearnum, 1), INTERVAL (@weeknum - 1) WEEK))) DAY
) AS MondayOfWeek;

遵循ISO周规则的话,直接用字符串构造:

SET @yearnum = 2022, @weeknum = 50;
SELECT STR_TO_DATE(CONCAT(@yearnum, 'W', LPAD(@weeknum, 2, '0'), '1'), '%X%V%w') AS MondayOfWeek;

PostgreSQL

遵循ISO周规则的写法最直接:

SELECT to_date(concat(2022, ' ', 50, ' ', 1), 'IYYY IW ID') AS monday_of_week;

参数说明:IYYY=ISO年,IW=ISO周,ID=ISO周内的天数(1=周一)。

内容的提问来源于stack exchange,提问作者hdeguzm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 22:08:10