Как преобразовать номер недели и день недели в дату - PullRequest
0 голосов
/ 15 января 2019

У меня есть файлы CVS, которые содержат информацию о дате в трех отдельных столбцах, которые я хотел бы объединить. У меня есть информация:

  • Двузначный год (поле 2)
  • Номер недели (поле 3)
  • Номер дня недели (поле 4)

Как я могу преобразовать эти 3 числа в обычный формат даты в форме YYYYMMDD?

Мой входной файл выглядит так:

740054,17,40,1,0000000000001,25,25,test1,1
740054,17,40,2,0000000000001,24,24,test2,1
740054,17,40,4,0000000000001,19,19,test3,1

И ожидаемый результат, который я хотел бы получить:

740054,20171002,0000000000001,25,25,test1,1
740054,20171003,0000000000001,24,24,test2,1
740054,20171005,0000000000001,19,19,test3,1

В качестве примера для первой строки: 2 октября 2017 года - понедельник (1) 40-й недели 2017 года

Кто-нибудь знает, как сделать такое преобразование?

1 Ответ

0 голосов
/ 15 января 2019

Я сделаю предположение, что номер вашей недели соответствует определению ISO 8601 (другие определения см. здесь ). Этот стандарт ISO 8601 широко используется в мире: ЕС и большинство других Европейские страны, большая часть Азии и Океания

Стандарт ISO 8601 гласит следующее:

  • В неделе 7 дней
  • Первый день недели - Понедельник
  • Первая неделя - это первая неделя года, которая содержит четверг . Это означает, что это первая неделя с 4 днями и более в январе.

При таком определении можно иметь номер недели 53. Это происходит с первого января по Пятница (например, 2016-01-01, 2010-01-01). Или, если годом ранее был високосный год, также суббота. (Например, 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

Учитывая year, week_number и day_of_week, как мы можем восстановить дату? Ответ требует нескольких шагов и вычислит день года (doy) запрошенной даты.

Чтобы вычислить день года doy, сначала нам нужно выяснить, когда начинается первая неделя, как объяснено выше. Если 01 января - вторник, то первая неделя содержит только 6 дней, а не 7, а если 01 января - пятница, первая неделя начинается только через неделю. Таким образом, мы можем решить это, добавив смещение. Смещение можно найти в следующей таблице:

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

и это смещение вычисляется как 3-(dow001+2)%7

Таким образом, день года очень легко вычисляется:

doy = (week_number-1) * 7 + 3-(dow001+2)%7 + day_of_week

Итак, имея это, мы можем написать следующий инструмент GNU awk:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...