SQLite 返回错误的 2013 周数?

问题描述 投票:0回答:3

我有一个简单的 SQL 用于计算 SQLite 报告中的周数

SELECT STRFTIME('%W', 'date_column')

2009-2012 年是正确的。在 2013 年,我总是得到错误的周数。

例如

SELECT STRFTIME('%W', '2012-02-28')

返回 '09',这是正确的。

SELECT STRFTIME('%W', '2013-02-28')

return '08' 这是错误的。我们有第 9 周。

SQLite 日期时间函数中有什么我不明白的吗?还是 SQLite 的 bug?

sqlite strftime week-number
3个回答
12
投票

CL 的答案适用于 OP 对“正确”的定义,这与 ISO 定义不太一样。 ISO 周数始终在 1-53 范围内(没有第 0 周),一年的最后 3 天可能会落入下一年的第 1 周,就像前 3 天可能会落入 52 周或 53 周一样前一年。要考虑这些极端情况,您需要执行以下操作:

SELECT
    (strftime('%j', date(MyDate, '-3 days', 'weekday 4')) - 1) / 7 + 1 AS ISOWeekNumber
FROM MyTable;

作为旁注,SQLite 的日期和时间 文档确实链接到POSIX strftime 手册页,它将

%W
修饰符定义为: “一年中的周数(星期一作为一周的第一天)作为十进制数 [00,53]。第一个星期一之前的新年中的所有日子都被认为是在第 0 周。


5
投票

从 SQLite 的未记录的周定义(第一周是一年中第一个星期一的那一周,或其中有 1 月 7 日的那一周)转换为 ISO 周定义(第一周是一年中第一个星期二的那一周,或其中包含 1 月 4 日的那一周),我们让 SQLite 计算一年中 1 月 4 日所在的那一周。如果那不是一个,我们必须增加周数:

SELECT strftime('%W', MyDate)
       + (1 - strftime('%W', strftime('%Y', MyDate) || '-01-04'))
FROM MyTable

0
投票

根据 srdan 的回答,这是一个完整的解决方案,其中包括与确定的周数相对应的年份。这个表达式产生一个有效的 ISO 8601 周规范,并且可以按原样用于基于完整连续周的统计查询(没有新年前后奇怪的拆分行为)。

select format('%04d', strftime('%Y', date(_time_, '-3 days', 'weekday 4'))) || '-W' ||
    format('%02d', (strftime('%j', date(_time_, '-3 days', 'weekday 4')) - 1) / 7 + 1);
  • 2020-01-01 的示例:2020-W01
  • 2020-12-31 示例:2020-W53
  • 2021-01-01 的示例:2020-W53
  • 2021-12-31 示例:2021-W52
  • 2022-01-01 的示例:2021-W52
  • 2022-12-31 示例:2022-W52
  • 2023-01-01 的示例:2022-W52
  • 2023-12-31 示例:2023-W52
  • 2024-01-01 的示例:2024-W01
  • 2024-12-31 示例:2025-W01

PS:如果您收到

format
函数未定义的错误,请将其替换为旧别名
printf
。我找不到它是在哪个 SQLite 版本中更改的。

© www.soinside.com 2019 - 2024. All rights reserved.