0

How can I get the ISO date for a specific week's Monday? For example, the Monday of the 32nd week of 2021?

I know that if I run date -dmonday +%Y%m%d I will get the the Monday date of the current week. How can I pass the 2021 and 32 as variables, and get the date of the Monday of that week?

4
  • 1
    The -d flag isn't standard, should we assume you are using Linux, or at least GNU date? Commented Feb 2, 2022 at 9:50
  • @terdon I'm using debian Commented Feb 2, 2022 at 9:56
  • 1
    You have to tell us what the definition is of the "first week" is. This varies according to local custom. For example is Jan 1 always in week 1? Does a week start on a particular day (which one)? Commented Feb 2, 2022 at 10:21
  • @icarus thank you. For me it's ok the ISO week number, with Monday as first day of week (01..53). My locale is the one for Italy Commented Feb 2, 2022 at 10:26

4 Answers 4

3

This seems to work correctly.

#! /bin/bash year=$1 week=$2 read s w d < <(date -d $year-01-01T13:00 '+%s %V %u') (( s += ((week - w) * 7 - d + 1) * 24 * 60 * 60 )) date -d @$s '+%V:%w %Y-%m-%d %a' 

Tested with

for y in {1970..2022} ; do maxw=$(date +%V -d $y-12-31) if (( max == 1 )) ; then # The last day of the year belongs to week #1. max=52 fi for ((w=1; w<=maxw; ++w)) ; do date.sh $y $w | tail -n1 | grep -q "0\?$w:1 " || echo $y $w done done 

where date.sh is the above script.

2
  • Nice choice to set a time, I should adopt it in my solution. Commented Feb 2, 2022 at 11:13
  • 1
    @icarus: It avoids problems with daylight savings times randomly shifting the date to a neighbouring day :-) Commented Feb 2, 2022 at 11:45
2

Wikipedia has an article on ISO week dates The "first week" is defined to be the one with the first thursday in it. The article states that this is equivalent to Jan 4th is always in week 1. GNU date allows you to give dates like date -d "Jan 4 2021 +3 weeks" which will get you a date in the 4th week, not usually a monday.

Using date we can find the day of the week, and use that to adjust the date to ask for.

#!/bin/bash # pass in $1 as the week number and $2 as the year # Make sure we are no going to be bothered by daylight saving time # Use explicit time idea from https://unix.stackexchange.com/a/688968/194382 export TZ=UTC # Jan 4th is always in week 1. ask for the day of the week that is # $1-1 weeks ahead. %u gives 1 for Monday, 2 for tuesday, ... weekday=$(date -d"13:00 Jan 4 $2 +$(($1 -1)) weeks" "+%u") # So now just go back 0 days for a monday, 1 day for tuesday ... # Could use Jan 5 and go back 1 day for monday instead. date -d"13:00 Jan 4 $2 +$(($1 -1)) weeks -$((weekday -1)) days" "+%a %F (%G %V)" 

So for 2021 this shows the monday of week 1 was 2021-01-04, and for 2020 it was 2019-12-30 (i.e. at the end of the previous year)

1

This works at least from 2000 to 2025:

Y=2021 W=32 LC_ALL=C date -d"${Y}0101 ${W} week -$(date -d"${Y}0104" +%u) day -3day" Mon Aug 9 00:00:00 CEST 2021 

The LC_ALL=C prefix eliminates locale influences.

0
1

via python it is possible to do with oneliner:

echo "2021 32"| python3 -c 'import datetime as dt; print(dt.datetime.strptime(input()+" 1", "%G %V %u").strftime("%Y-%m-%d"));' 2021-08-09 

you can wrap it into a BASH function and then use it clearly for any other day of week 1..7, for example for Wednesday (day=3):

> iso_year_week_day() { echo "$1 $2 $3" | python3 -c 'import datetime as dt; print(dt.datetime.strptime(input(), "%G %V %u").strftime("%Y-%m-%d"));'; } > > iso_year_week_day 2021 32 3 2021-08-11 > iso_year_week_day 2022 52 7 2023-01-01 > q=$(iso_year_week_day 2021 32 3) > echo $q 2021-08-11 

P.S. of course output format can be easily adjusted by editing strftime("%Y-%m-%d")

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.