计算去年当前周开始日期和结束日期

时间:2012-01-24 20:14:35

标签: mysql

我正在尝试计算“当前周NOW()”的最后几年开始日和该周的结束日。除此之外,我需要一个补偿,因为有时一周的开始日可能不是星期日或星期一,但甚至可能是星期四。

如果一周从星期二开始,它将在星期一结束。鉴于此,如果当天是星期四,我需要能够计算星期二和星期一。

我知道如何获得去年的当天。

SELECT DATE_SUB(NOW(), INTERVAL 1 YEAR);

但是根据抵消要求,我在计算该周的开始日和该周的结束日期时遇到了问题。哪个需要采用“日期格式”。

* 努力澄清这一点......我的例子已经关闭......

***修改

为了争论(和例子),让我们说今天是2012年1月23日。我的任务是接受该日期并返回上一年那一周的开始和结束日期。

我的假设是:

1) a week is defined as having a thursday (ie 2011 week 1 is 1/2 - 1/8)
2) start of week is Sunday

根据我用上述假设所理解的周编号方案,第1周是星期四的第一周。这意味着,1月23日在2012年的第4周内。这已通过WEEK('2012-01-04') = 4确认。因此,我的目标是选择上一年第4周的开始和结束日期。 2011年,结果将是1月23日至1月29日。

然后进一步复杂化是调整一周的开始(修改假设2)。继续使用WK4 ... 2011年1月23日 - 1月29日,周日 - 周六,如果我说本周开始是周一,那么我会将日期调整为1 ...给1月24日 - 1月30日。周二调整2月1日 - 1月25日 - 1月31日等。

方法分为两步:     1)计算 true 年周的开始和结束     2)无论开始日是什么,都将它滑入“未来”

虽然滑入未来可能会或可能不正确,但根据对“第4周”的含义的传统理解,它至少会产生一致的结果。

不幸的是,PHP不一定是一个选项。我们需要在SELECT START_WEEK,END_WEEK中运行它;

任何有关解决此查询的建议或帮助都会有所帮助。

由于

2 个答案:

答案 0 :(得分:1)

好吧,ISO 8601假设:

  1. 一周被定义为具有星期四
  2. 一周的开始是Mon
  3. 1月23日属于2012年第4周,您可以通过

    确认
    SELECT WEEK('2012-01-23', 3) = 4;
    

    2012年第4周是1月23日至1月29日,您可以通过whatweekisit.com的日历确认。作为查询,您可以使用以下方式计算:

    SELECT
        WEEK('2012-01-23', 3) AS weekNumber,
        DATE_SUB('2012-01-23', INTERVAL DAYOFWEEK('2012-01-23') - 2 DAY) AS startOfWeek,
        DATE_ADD('2012-01-23', INTERVAL 8 - DAYOFWEEK('2012-01-23') DAY) as endOfWeek;
    

    2011年第4周是1月24日至1月30日(也可通过日历确认)。确实,同一日期可能不在当前周数和去年的一周内,但我不怀疑它们会有很大不同。

    SELECT
        IF (WEEK('2012-01-23', 3) = WEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), 3),
            DATE_SUB(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR)) - 2 DAY),
            DATE_SUB(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR)) - 2 DAY)) AS datetimeStart;
    

    请注意,我总是在几个地方逐字表示计算(例如2011年1月32日的DATE_SUB('2012-01-23', INTERVAL 1 YEAR));如果您在存储过程或UDF中执行此操作,则可以使用变量使其更简洁/可读/可维护。

    现在已经确定了目标年份周的开始和结束,您可以简单地应用您的偏移量。鉴于$weekDayStart为0 - 6(周日 - 周六):

    SELECT
        DATE_ADD(
            IF (WEEK('2012-01-23', 3) = WEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), 3),
                DATE_SUB(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR)) - 2 DAY),
                DATE_SUB(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR)) - 2 DAY)),
            INTERVAL $weekDayStart - 1 DAY) AS datetimeStart,
    
        DATE_ADD(
            IF (WEEK('2012-01-23', 3) = WEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), 3),
                DATE_SUB(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR)) - 2 DAY),
                DATE_SUB(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR)) - 2 DAY)), 
            INTERVAL $weekDayStart + 5 DAY) AS datetimeEnd;
    

    因此,通过2012-01-23的输入和周四的开始日来完成它将产生:

    1. 2012年1月23日 =第4周
    2. 2011年第4周= 1 / 24-1 / 30
    3. 偏离星期四 - 星期一(4 - 1)为+3,将窗口移至 2011年1月27日至2月2日

答案 1 :(得分:0)

找到它......不得不再多阅读一下这个问题。 这最终成了7个不同的查询。

我的基本查询:

Sunday Start Day of Week
SELECT 
DATE_SUB(
DATE_ADD( 
STR_TO_DATE( CONCAT( YEAR('2012-01-04')-1, '-01-01' ), '%Y-%m-%d'), #Get last year starting date. 
INTERVAL WEEK('2012-01-04') WEEK),
INTERVAL 6 DAY) START_DAY_OF_WEEK,
DATE_ADD( 
STR_TO_DATE( CONCAT( YEAR('2012-01-04')-1, '-01-01' ), '%Y-%m-%d'),
INTERVAL WEEK('2012-01-04') WEEK) END_DAY_OF_WEEK;

这让我在2011年第1周开始。那个星期的开始是1/2,结束于1/8。 现在,如果我的星期在不同的一天开始,我会添加一个偏移...

Tuesday Start Day of Week
SELECT 
DATE_SUB(
DATE_ADD( 
STR_TO_DATE( CONCAT( YEAR('2012-01-04')-1, '-01-01' ), '%Y-%m-%d'), #Get last year starting date. 
INTERVAL WEEK('2012-01-04') WEEK),
INTERVAL 4 DAY) START_DAY_OF_WEEK,
DATE_ADD(
DATE_ADD( 
STR_TO_DATE( CONCAT( YEAR('2012-01-04')-1, '-01-01' ), '%Y-%m-%d'), #Get last year starting date. 
INTERVAL WEEK('2012-01-04') WEEK),
INTERVAL 2 DAY) END_DAY_OF_WEEK;

这将给我1/4周的开始日,并以1/10结束。

要获得一周中的其他日子相对简单:

  • 星期天(第一次质询......)
  • 星期一-5开始日+1结束日。
  • 周二-4开始日+2结束日。
  • 周三-3开始日+3结束日。
  • 星期四-2开始日 - 结束日。
  • 星期五-1开始日-5结束日。
  • 周六-0开始日 - 结束日。

这是7个单独的查询,但确实使我能够做我想做的事。