已知周数,如何在MySQL中获取对应周的起止日期?
根据MySQL WEEK()返回的0-53周数获取周起止日期(周一至周日)
首先得明确:你用的WEEK(date, 1)函数(返回0-53,周一为一周起始),周数0对应的是当年第一个周一之前的那一周(可能跨年前一年),周1及以后是当年内的正常周。下面提供两种可靠的实现方法:
方法一:通用公式法(无需分支处理周0)
这种方法可以统一处理周0到53的所有情况,不用单独判断周数是否为0:
假设你已经有年份变量@year和周数变量@week(比如@year=2018,@week=0),执行以下SQL就能直接拿到周一(开始)和周日(结束):
SET @year = 2018; SET @week = 0; SELECT -- 计算该周的周一(开始日期) MAKEDATE(@year, 1) + INTERVAL (0 - WEEKDAY(MAKEDATE(@year, 1))) % 7 DAY + INTERVAL (@week - 1)*7 DAY AS week_start, -- 计算该周的周日(结束日期) MAKEDATE(@year, 1) + INTERVAL (0 - WEEKDAY(MAKEDATE(@year, 1))) % 7 DAY + INTERVAL (@week - 1)*7 DAY + INTERVAL 6 DAY AS week_end;
原理说明:
MAKEDATE(@year, 1):得到当年的1月1日(0 - WEEKDAY(MAKEDATE(@year, 1))) %7 DAY:计算1月1日到当年第一个周一的间隔天数(如果1月1日就是周一,间隔为0)- 加上
(@week-1)*7天:周1就是第一个周一,周0就是第一个周一减7天,周2就是第一个周一加7天,以此类推 - 最后加6天得到周日(因为周一加6天就是周日)
方法二:STR_TO_DATE构造法(需处理周0)
利用MySQL的日期格式化函数STR_TO_DATE,但因为%V格式符只接受1-53的周数(对应周一为起始的周),所以周0需要单独处理为上一年的最后一周:
情况1:周数≥1(当年正常周)
SET @year = 2018; SET @week = 2; SELECT STR_TO_DATE(CONCAT(@year, '-', @week, '-1'), '%X-%V-%w') AS week_start, -- 周一 STR_TO_DATE(CONCAT(@year, '-', @week, '-0'), '%X-%V-%w') AS week_end; -- 周日
%X:周所属的年份%V:1-53的周数(周一为起始)%w:星期几(0=周日,1=周一)
情况2:周数=0(跨年周)
SET @year = 2018; SET @week = 0; SELECT -- 上一年最后一周的周一 STR_TO_DATE(CONCAT(@year-1, '-', WEEK(DATE_SUB(MAKEDATE(@year,1), INTERVAL 1 DAY), 3), '-1'), '%X-%V-%w') AS week_start, -- 上一年最后一周的周日 STR_TO_DATE(CONCAT(@year-1, '-', WEEK(DATE_SUB(MAKEDATE(@year,1), INTERVAL 1 DAY), 3), '-0'), '%X-%V-%w') AS week_end;
DATE_SUB(MAKEDATE(@year,1), INTERVAL 1 DAY):拿到当年1月1日的前一天(即上一年最后一天)WEEK(..., 3):用模式3(周一为起始,返回1-53周数)得到该天所属的周数- 再用
STR_TO_DATE构造出该周的起止日期
验证示例
比如你提到的2018年1月1日是周一:
- 当
@year=2018,@week=1时,两种方法都会返回week_start=2018-01-01,week_end=2018-01-07 - 当
@year=2018,@week=0时,返回week_start=2017-12-25,week_end=2017-12-31,这符合WEEK('2017-12-25',1)=0的结果
内容的提问来源于stack exchange,提问作者Saswat
相关产品推荐
相关产品推荐

