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