I will make the assumption that your week-number is according to the ISO 8601 definition (for other definitions see here). This ISO 8601 standard is widely used in the world: EU and most of other
European countries, most of Asia, and Oceania
The ISO 8601 standard states the following:
- There are 7 days in a week
- The first day of the week is a Monday
- The first week is the first week of the year which contains a
Thursday. This means it is the first week with 4 days or more
in January.
With this definition, it is possible to have a week number 53. These occur with the first of January is on a
Friday (E.g. 2016-01-01, 2010-01-01). Or, if the year before was a
leap year, also a Saturday. (E.g. 2005-01-01)
December 2015 January 2016
Mo Tu We Th Fr Sa Su CW Mo Tu We Th Fr Sa Su CW
1 2 3 4 5 6 49 1 2 3 53
7 8 9 10 11 12 13 50 4 5 6 7 8 9 10 01
14 15 16 17 18 19 20 51 11 12 13 14 15 16 17 02
21 22 23 24 25 26 27 52 18 19 20 21 22 23 24 03
28 29 30 31 53 25 26 27 28 29 30 31 04
Given the year, week_number and day_of_week, how can we reconstruct the date? The answer requires several steps and will compute the day of the year (doy) of the requested date.
To compute the day of the year doy we first need to figure out when the first-week starts as explained above. If Jan 01 is a Tuesday, then the first week only contains 6 days and not 7, while if Jan 01 is a Friday, the first week starts only the week after. So we can solve this by adding an offset. The offset can be found in the following table:
dow001 str: Mo Tu We Th Fr Sa Su
dow001 num: 01 02 03 04 05 06 07
offset : 0 -1 -2 -3 3 2 1
and this offset is computed as 3-(dow001+2)%7
So with this, the day of the year is very easily computed:
doy = (week_number-1) * 7 + 3-(dow001+2)%7 + day_of_week
So having this, we can write the following GNU awk tool:
awk 'function compute_date(YYYY,CW,DOW) {
dow001 = strftime("%u",mktime(YYYY " 01 01 00 00 00"))
doy = (CW-1)*7 + (3 - (dow001+2)%7) + DOW
return strftime("%Y%m%d",mktime(YYYY " 01 " doy " 00 00 00"))}
}
BEGIN { FS = OFS = "," }
{ datestr = compute_date(2000+$2,$3,$4) }
{ print $1, datestr , $5,$6,$7,$8,$9 }' file
740054,20171002,0000000000001,25,25,test1,1
740054,20171003,0000000000001,24,24,test2,1
740054,20171005,0000000000001,19,19,test3,1