Subject: bug#13372: bug in date with last week calculation

From: Bob Proulx <[email-masked]>
Date: Sun, 6 Jan 2013 23:57:22 -0700

Tomas Dabašinskas wrote:
> I'm getting week number 53 when trying to get last week on
> Mon Jan  7 09:46:19 EST 2013:
>
> $ date
> Mon Jan  7 09:46:19 EST 2013
> $ date -d'last week' +%W
> 53
>
> Expecting to get week 1

You are using %W which is described as:

  `%W'
     week number of year, with Monday as first day of week
     (`00'...`53').  Days in a new year preceding the first Monday are
     in week zero.

And so:

     December 2012      
  Mo Tu We Th Fr Sa Su
  24 25 26 27 28 29 30  <-- week 52
  31                    <-- week 53
      January 2013
  Mo Tu We Th Fr Sa Su
      1  2  3  4  5  6  <-- week 0
   7  8  9 10 11 12 13  <-- week 1
  14 15 16 17 18 19 20  <-- week 2
  21 22 23 24 25 26 27
  28 29 30 31

Since you are reporting your current time as Jan 7 then Dec 31 would
be last week.  Dec 31 would be week 53.

  $ env TZ=Australia/Sydney date -d 'last week' -R
  Mon, 31 Dec 2012 16:59:04 +1100

And so:

  $ env TZ=Australia/Sydney date -d 'last week' +%W
  53

  $ env TZ=Australia/Sydney date -d 'Dec 31 2012 12:00 +0000' +%W
  53

There are multiple different definitions for week numbers depending
upon weeks starting on Sunday, starting on Monday, and so forth.

Also related are:

  `%U'
     week number of year, with Sunday as the first day of the week
     (`00'...`53').  Days in a new year preceding the first Sunday are
     in week zero.

  `%V'
     ISO week number, that is, the week number of year, with Monday as
     the first day of the week (`01'...`53').  If the week containing
     January 1 has four or more days in the new year, then it is
     considered week 1; otherwise, it is week 53 of the previous year,
     and the next week is week 1.  (See the ISO 8601 standard.)

You might want to look at the strftime man page for an alternate
description:

  man 3 strftime

       %U     The  week  number of the current year as a decimal number, range
              00 to 53, starting with the first Sunday as  the  first  day  of
              week 01.  See also %V and %W.

       %V     The  ISO 8601  week  number (see NOTES) of the current year as a
              decimal number, range 01 to 53, where week 1 is the  first  week
              that  has  at least 4 days in the new year.  See also %U and %W.
              (SU)

       %W     The  week  number of the current year as a decimal number, range
              00 to 53, starting with the first Monday as  the  first  day  of
              week 01.

   ISO 8601 Week Dates
       %G, %g, and %V yield values calculated from the week-based year defined
       by the ISO 8601 standard.  In this system, weeks start on a Monday, and
       are numbered from 01, for the first week, up to 52 or 53, for the  last
       week.  Week 1 is the first week where four or more days fall within the
       new year (or, synonymously, week 01 is: the first week of the year that
       contains  a  Thursday;  or,  the  week that has 4 January in it).  When
       three of fewer days of the first calendar week of  the  new  year  fall
       within that year, then the ISO 8601 week-based system counts those days
       as part of week 53 of the preceding year.  For example, 1 January  2010
       is a Friday, meaning that just three days of that calendar week fall in
       2010.  Thus, the ISO 8601 week-based system considers these days to  be
       part  of  week 53 (%V) of the year 2009 (%G) ; week 01 of ISO 8601 year
       2010 starts on Monday, 4 January 2010.

Perhaps you are looking for the ISO week date %V?  And if just doing
calculations I suggest using UTC.

  $ date -u -d 'Dec 31 2012 12:00 +0000' +%V
  01

The 'ncal' program provides a useful but unusual way to display the
ISO week numbers:

  $ ncal -A 1 -w 12 2012
      December 2012     January 2013
  Su     2  9 16 23 30     6 13 20 27
  Mo     3 10 17 24 31     7 14 21 28
  Tu     4 11 18 25     1  8 15 22 29
  We     5 12 19 26     2  9 16 23 30
  Th     6 13 20 27     3 10 17 24 31
  Fr     7 14 21 28     4 11 18 25
  Sa  1  8 15 22 29     5 12 19 26
     48 49 50 51 52  1  1  2  3  4  5

You should also read the FAQ:

  http://www.gnu.org/software/coreutils/faq/#The-date-command-is-not-working-right_002e

No one is ever happy with week numbers.

Bob