【问题标题】:Week of the year for weeks starting with Saturday一年中的一周,从星期六开始的几周
【发布时间】:2012-05-18 17:17:00
【问题描述】:

我们的客户目前已定义从周六、周日或周一开始的周数。遇到了这些 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

【问题讨论】:

    标签: mysql date


    【解决方案1】:

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

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

    例如:

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

    我做了这个声明,根据这些规则计算 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 周,则将另一个添加到年份。

    【讨论】:

      【解决方案2】:

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

      ISO standard 定义从星期一开始的第一周并包含一年中的第四天。 MySQL的函数提供much more choices

      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);
      

      第一个表达式非常简单。

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

      • 对于第一种情况(第一周从第一个星期六开始),我以一年中的 Jan/1 为主题的星期几,将星期六作为日期0,然后调整 day-of-年的差异。这使得第一个星期六之前的所有日子都产生负调整数,并且上限为零;
      • 对于第二种情况(第一周是一年中的第 4 天),我将一年中的 1 月 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 用于补充周三到 7 的 dayofweek() 值。

      【讨论】:

        【解决方案3】:

        根据DAYOFWEEK()进行调整。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-11-29
          • 1970-01-01
          • 2021-01-29
          • 2011-06-27
          • 2023-03-28
          • 2012-11-27
          • 2017-12-14
          • 1970-01-01
          相关资源
          最近更新 更多