MySQL WEEK()函数的哪种模式符合ISO 8601标准?

62

MySQL的WEEK()函数的哪种模式可以得到ISO 8601年的周数WEEK()函数的第二个参数按照此表设置模式:

+--------------------------------------------------------------------+
| Mode | First day of week | Range | Week 1 is the first week ...    |
|------+-------------------+-------+---------------------------------|
| 0    | Sunday            | 0-53  | with a Sunday in this year      |
|------+-------------------+-------+---------------------------------|
| 1    | Monday            | 0-53  | with more than 3 days this year |
|------+-------------------+-------+---------------------------------|
| 2    | Sunday            | 1-53  | with a Sunday in this year      |
|------+-------------------+-------+---------------------------------|
| 3    | Monday            | 1-53  | with more than 3 days this year |
|------+-------------------+-------+---------------------------------|
| 4    | Sunday            | 0-53  | with more than 3 days this year |
|------+-------------------+-------+---------------------------------|
| 5    | Monday            | 0-53  | with a Monday in this year      |
|------+-------------------+-------+---------------------------------|
| 6    | Sunday            | 1-53  | with more than 3 days this year |
|------+-------------------+-------+---------------------------------|
| 7    | Monday            | 1-53  | with a Monday in this year      |
+--------------------------------------------------------------------+

这些模式中是否有一种可以给出 ISO 8601 年份的周数?


13
+1 是为了更好的搜索友好性(我谷歌搜索了“mysql week ISO-8601”,这个问题是第一个结果)。 - Hnatt
这不是指今年有4天或更多天吗?:https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_week - Yahya Uddin
4个回答

87
在ISO周编号中,周一是一周的第一天,这就将其缩小到了奇数模式之一。维基百科上说:

周01有互相等价的定义:

  • 年份的第一个星期四所在的周(ISO的正式定义)
  • 包含1月4日的那一周
  • 年初的大多数(四天或更多)所在的第一个星期
  • 从12月29日至1月4日期间的周一开始的那一周
以上第三个描述与上面表格中“今年超过3天”的定义相匹配,因此现在我们已将答案缩小到了1或3。
最后,还是引用维基百科的原话(重点标出):

如果1月1日是周一、周二、周三或周四,则它在第01周。如果1月1日是周五、周六或周日,则它在上一年的第52或53周(没有第00周)

因此,范围必须是1-53,而不是0-53。这反过来意味着正确的模式是模式3

要验证此答案是否正确,请参考ISO 8601第2.2.8节和第2.2.10节中“日历周”和“日历周数”的官方定义。为了澄清为什么没有第0周,“日历周数”被定义为“序数”,而序数从1开始。 - TachyonVortex
我在维基百科上读到“今年只有3天”而不是“今年超过3天”。最后我弄清楚了。感谢这个解释得很好的答案! - Adam
1
我仍然认为“3”应该是默认模式,因为它对应于我们大多数人使用的日历。出于某种书呆子的原因,这是一种允许“第0周”的模式,我必须提醒自己并谷歌这些模式,以避免潜在的客户灾难。 - kasimir

35

我知道这个问题很久了,但是它在搜索引擎优化方面排名很高。所以为了让答案更加完整 - 在显示年份和周数时,你可以使用以下内容:

DATE_FORMAT(your_date_here, "%x-%v")

它将生成%v(1-53)的ISO周数和%x的正确年份。


3
好的,非常适合报道!谢谢! - Ross
4
为了使其符合 ISO-8601 标准,它必须具有格式 '%x-W%v' 或 '%xW%v'。 - gosuto
为了将其与其他答案联系起来,MySQL文档表示%v是模式3:%v周(01..53),其中星期一是一周的第一天; WEEK()模式3;与%x一起使用。 - jacobmovingfwd

5

ISO 8601的答案是模式3

SELECT week(your_date_column, 3) FROM your_table

1

对于法国,您需要在文件/etc/mysql/my.cnf中添加以下内容§ [Mysqld]:default_week_format = 3

注意:对于YEARWEEK无效,需要添加mode = 3 SELECT YEARWEEK(CURDATE(),3)

对于法国,请在文件/etc/mysql/my.cnf的[Mysqld]段中修改或添加以下行:default_week_format = 3。这使得WEEK函数返回真正的法国周数。请注意,对于YEARWEEK函数,必须添加模式为3 SELECT YEARWEEK(CURDATE(),3)


1
我对你的帖子很感兴趣,但是我不会读法语。Stack Overflow似乎更偏爱英语。 - steampowered

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接