2

我们的客户目前已定义从周六、周日或周一开始的周数。遇到了这些 DATE_FORMAT 选项,它们可以很好地处理从周日和周一开始的一周,但找不到从周六开始的一周的方法。有什么建议么?

%U    Week (00..53), where Sunday is the first day of the week
%u    Week (00..53), where Monday is the first day of the week
4

3 回答 3

3

我有一个类似的问题:我需要根据以下规则计算周数:

  • 一周从星期五开始
  • 一年中的剩余天数(一年中最后一个星期五之后未完成一周的所有天数)应计入下一年的第一周。

例如:

  • 27/12/2012(星期四)应该是 2012 年的第 52 周
  • 28/12/2012(星期五)应该是 2013 年的第 1 周
  • 2013 年第 1 周从 28/12/2012 到 3/1/2013

我做了这个声明,根据这些规则计算 YEAR 和 WEEKNUMBER,您可以轻松地适应您的情况:

SELECT IF(ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7) > 52, YEAR(current_date)+1, YEAR(current_date)), 
        IF(ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7) > 52, 1, ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7));

棘手的部分就是这个表达式:

ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7)

其余的(If 子句)仅用于调整表达式的结果以使第 53 周的 year+1 和 week = 1。

我会尽力解释这个表达式。以下表达式为您提供了简单的周数(一年中的某一天除以一周中的 7 天,向上取整):

ceil(( dayofyear(current_date))/7)

但现在你想让它在星期五(或任何其他日子)开始。为此,您需要将第一周的天数添加到当前日期,这些天数是上一年的一部分(这就像您的当前实际上是几天前开始的,因为您的第一周包含前一年的天数)。此表达式根据 1 月 1 日的工作日计算该偏移量:

dayofweek(date_format(current_date, '%Y-01-01'))+OFFSET

偏移量是 7 和您希望一周开始的 weekdaynumber 之间的差:

  • 周六 0
  • 1 周五
  • 2 星期四
  • 3 周三...

因此,现在您只需将其添加到前一个表达式中,即可得到上述表达式,该表达式计算从任何工作日开始的周数,并假设第 1 周从上一年开始:

ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+OFFSET )/7)

然后我只是添加了一个 IF 将第 53 周变为第 1 周,如果是第 53 周,则将另一个添加到年份。

于 2013-04-18T12:23:10.073 回答
2

我花了一段时间来思考这个问题。

ISO 标准定义了从星期一开始的第一周并包含一年中的第四天。MySQL 的函数提供了更多的选择

date_format()标志%U%u使用符号,其中第一周是第一次遇到星期日或星期一的一周。由于这不符合 ISO,我将提供两种变体。

如果要从星期六开始计算周数,并且第一年的一周是包含星期六的那一周,则可以使用以下表达式之一:

SELECT sign(dayofweek(current_date) - 7) + ceil(dayofyear(current_date)/7);
SELECT ceil((dayofyear(current_date)+
            (dayofweek(date_format(current_date, '%Y-01-01'))%7-7))/7);

如果第一年的一周是一年中的第四天,请使用:

SELECT ceil((dayofyear(current_date)+
            (dayofweek(date_format(current_date, '%Y-01-04'))%7-4+1))/7);

第一个表达式非常简单。

我将详细说明第 2 和第 3 个。我通过取一年中的当前日期,除以 7 和上限来计算周数,非常简单。周数需要根据年初的情况进行调整。

  • 对于第一种情况(第一周从第一个星期六开始),我将主题中的一年中的 Jan/1 设为星期几,将星期六作为日期0,然后根据差异调整一年中的日期。这使得第一个星期六之前的所有日子都产生负调整数,并且上限为零;
  • 对于第二种情况(第一周是一年中的 4 天),我将一年中的 Jan/4 设为星期几,将星期六设为日期0。该-4+1公式对 1 月 4 日之前的第一个星期六进行了调整,+1用于一年中的天数从 1 开始,而不是从 0 开始。负调整意味着一年中的第一天不在一年的第一周。

这是SQL Fiddle上的一些测试日期。

如果你想从其他任何一天开始计算周数,你只需要改变公式,让那一天0在序列中。比如说,要从星期三开始计算周数,请使用:

SELECT ceil((dayofyear(current_date)+
    ((dayofweek(date_format(current_date, '%Y-01-04'))+3)%7-4+1))/7);

+3用于补充dayofweek()周三到 7 的值。

于 2012-05-19T19:00:56.697 回答
0

根据 进行调整DAYOFWEEK()

于 2012-05-18T17:58:56.003 回答