How can I use the date command to convert something like "monday week 40" into a ISO date?

I am playing with something like this:

date --date='monday week 40' +'%Y-%m-%d'

And the date I'm searching for would be 2011-10-03.

But my problem is that this date string is not valid, so I need another approach to solve this problem.


  • The following link is about what determines on which day of the year a numbered week begins. Week numbering (Wikipedia).. It effectively explains why the 1st of Janunuary of this year is in ISO week 52 .. The %V format sequence used by 'user unknown' reports the ISO week number.
    – Peter.O
    Sep 1, 2011 at 16:16

3 Answers 3


An alternative approach:

date --date "+$((40-$(date +%V)))weeks last monday"  +"%F"
  • 40 is the week you search for
  • date +%V returns the current week (35)
  • 40-35 = 5, which is the number of weeks to add
  • from there, seek the last monday
  • good one, and it works with my custom date setting.
    – Peter.O
    Sep 1, 2011 at 14:31
  • This is a clever idea, but it doesn't work. For example, if today is Monday in week 41 (i.e. date +%V returns 41), then the --date parameter value will be +-1weeks last monday, which is actually a fortnight ago, not 7 days ago. Sep 2, 2013 at 11:09
  • I'm not sure whether I understand your critique. It's 2013 this year, so the example from the question doesn't fit. What should be the absolute date for the question, and what does my approach return instead (maybe: why)? Sep 2, 2013 at 22:32
  • @AdamSpiers: My calendar displays as Monday, week 40 the 30th of Sep. which is what my algo yields (today). Sep 2, 2013 at 22:38
  • @userunknown That's because you are testing your code today, which is a Tuesday, which comes after Monday. If you had tested your code yesterday, it would have broke. To make it more obvious, try running date -d 'last monday'. It will return yesterday. What do you think it would have said if you had run it yesterday? Sep 3, 2013 at 13:38

Really ugly and probably works only with GNU date:

date -d "$( date -d "$( date +'%Y-01-01' ) +40 weeks") -$( date -d "$( date +'%Y-01-01' ) +40 weeks" +'%w' ) days+1 day" +'%Y-%m-%d'

Tested only for your 3 October example, may fail for some other cases.

Update: If you have a non eng locale you need to specify the output from the inner date to get to to work. (And %F just is YYYY-MM-DD).

date -d "$(date -d "$(date +'%Y-01-01') +40 weeks" +"%F") -$(date -d "$(date +'%Y-01-01') +40 weeks" +%w) days +1 day" +"%F"
  • 1
    You missed to format the output from the inner date so the outer could use it correctly.
    – Johan
    Sep 1, 2011 at 11:19
  • @Johan, I had no problem with using the default format. Maybe it is locale specific? I use en_US. Good point anyway.
    – manatwork
    Sep 1, 2011 at 11:34
  • For the date I use the Swedish locale, so there is the difference.
    – Johan
    Sep 1, 2011 at 13:09
  • Thanks for the locale adjustment. I have a custom date format and had the same problem.. I had almost sorted it out, but now you've posted it I'll use your tweak; it's better.
    – Peter.O
    Sep 1, 2011 at 14:32
  • There was no requirement for this to be a one-liner. It would be better to split this into multiple lines, using temporary variables with descriptive names to make it clear how it works. It also assumes that Jan 1st is in the same week number each year, which is not the case as already noted by @Peter.O. Sep 2, 2013 at 11:16

OK, here's my attempt. It steals ideas from the other answers, and attempts to make the logic easier to follow. This is based on the ISO 8601 system, so it won't be correct if you live in countries such as USA or Canada, but should be easily adjustable for those countries.

# sets $week_start to a representation of Monday of the given week
# number formatted via the given format, and similarly sets
# $week_end to Friday of the same week.
get_week_range () {
    week_num="$1" date_format="$2"

    # Most of the world adhere to ISO 8601 which states that weeks begin on Monday
    # and Jan 4th is always in week #1:
    #   http://en.wikipedia.org/wiki/ISO_week_date
    # For other week numbering systems (e.g. USA, Canada), see:
    #   http://en.wikipedia.org/wiki/Seven-day_week#Week_numbering
    day_in_week_1=$( date +'%Y-01-04' )
    day_num_in_week_1=$( date -d $day_in_week_1 +%u ) # 1 is Monday
    days_from_week_1_start=$(( $day_num_in_week_1 - 1 ))
    # This is a Monday:
    start_of_week_1=$( date -d "$day_in_week_1 - $days_from_week_1_start days" +%F )

    week_delta="$(( $week_num - 1 ))"
    # Monday:
    week_start=$( date -d "$start_of_week_1 + $week_delta weeks"          +"$date_format" )
    # Friday:
    week_end=$(   date -d "$start_of_week_1 + $week_delta weeks + 4 days" +"$date_format" )

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .