26

Given day of year, how can I get the week of year by using Bash?

conandor
  • 3,637
  • 6
  • 29
  • 36
  • Although you might get an answer for this on here I think this question may be more appropriate for our sister site stackoverflow.com. – Chopper3 Jul 12 '10 at 09:51
  • 1
    Not only is it a programming question but looks suspiciously like homework to me. Incidentally, using Bash for this is a good example of using the wrong tool for a job. – John Gardeniers Jul 12 '10 at 10:04
  • 1
    +1 don't use Bash for date calculations - modern Linux/UNIX machines will ship with an up-to-date Python or Perl by default. Use the best tool for the job. –  Jul 12 '10 at 11:07

3 Answers3

47

Using the date command, you can show the week of year using the "%V" format parameter:

/bin/date +%V

You can tell date to parse and format a custom date instead of the current one using the "-d" parameter:

/bin/date -d "20100215"

Then, mixing the two options, you can apply a custom format to a custom date:

/bin/date -d "20100215" +%V
Massimo
  • 1,520
  • 1
  • 19
  • 36
  • 1
    Too bad your solution only works with the GNU version of date. Solaris' version of date doesn't support the -d switch and the %V format option. – basvdlei Jul 12 '10 at 11:05
  • 6
    Also `%U` (Sunday start, 00-53) or `%W` (Monday start, 00-53) (in addition to `%V` (ISO, Monday start, 01-53)) depending on the week-numbering system you use. – Dennis Williamson Jul 12 '10 at 11:09
  • Solaris version of date, which unable to support -d can be resolve with replacing sunfreeware.com version of date. – conandor Oct 14 '10 at 04:00
  • 1
    Works on Mac OS X – Meredith Mar 02 '18 at 00:08
5

If you're using GNU date you can use relative dates like this:

$ doy=193
$ date -d "Jan 1 +$((doy -1)) days" +%U
28

This would give you a very simplistic answer, but doesn't rely on date:

$ echo $((doy / 7))

which pays no attention to the day of week.

Here's a demonstration of the week numbering systems:

$ printf "\nDate\t\tDOW\tDOY\t%%U %%V %%W\n"; \
for d in "Jan "{1..4}" 2010" \
"Dec "{25..31}" 2010" \
"Jan "{1..4}" 2011"; \
do printf "%s\t" "$d"; \
date -d "$d" +"%a%t%j%t%U %V %W"; \
done

Date            DOW     DOY     %U %V %W
Jan 1 2010      Fri     001     00 53 00
Jan 2 2010      Sat     002     00 53 00
Jan 3 2010      Sun     003     01 53 00
Jan 4 2010      Mon     004     01 01 01
Dec 25 2010     Sat     359     51 51 51
Dec 26 2010     Sun     360     52 51 51
Dec 27 2010     Mon     361     52 52 52
Dec 28 2010     Tue     362     52 52 52
Dec 29 2010     Wed     363     52 52 52
Dec 30 2010     Thu     364     52 52 52
Dec 31 2010     Fri     365     52 52 52
Jan 1 2011      Sat     001     00 52 00
Jan 2 2011      Sun     002     01 52 00
Jan 3 2011      Mon     003     01 01 01
Jan 4 2011      Tue     004     01 01 01
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
0

Adding to the other answers, I'd like to point out that there are different ways of enumerating the weeks of a year. For example, ncal displays a calendar, and when you pass it the -w argument, the week numbers are also indicated:

sudo apt install ncal
ncal -3wb
      December 2021              January 2022               February 2022        
 w| Su Mo Tu We Th Fr Sa    w| Su Mo Tu We Th Fr Sa    w| Su Mo Tu We Th Fr Sa   
49|           1  2  3  4    1|                    1    6|        1  2  3  4  5   
50|  5  6  7  8  9 10 11    2|  2  3  4  5  6  7  8    7|  6  7  8  9 10 11 12   
51| 12 13 14 15 16 17 18    3|  9 10 11 12 13 14 15    8| 13 14 15 16 17 18 19   
52| 19 20 21 22 23 24 25    4| 16 17 18 19 20 21 22    9| 20 21 22 23 24 25 26   
 1| 26 27 28 29 30 31       5| 23 24 25 26 27 28 29   10| 27 28                  
                            6| 30 31

Notice that January "touches" six (Sunday through Saturday) weeks, and while there is only one day (of 2022) in this first week, it's counted as the end of week 1 in this methodology. Also notice that the last six days of December are also considered part of week 1.

Lonnie Best
  • 9,936
  • 10
  • 57
  • 97