Shell

日期轉換未按預期工作

  • November 3, 2021

我有一個包含這種格式記錄的文件:

D20220327,S2927,977,1

D20220328,S2927,977,1

D20220329,S2927,977,1

D20220330,S2927,977,1

D20220331,S2927,977,1

D20220401,S2927,977,1

D20220402,S2927,977,1

D20220403,S2927,977,1

D20220404,S2927,977,1

但是,在應用轉換以將這些轉換為過去 7 天之後,它不適用於從 3 月 28 日到 4 月 3 日的日期,但是相同的程式碼邏輯在 3 月 27 日和 4 月 4 日可以正常工作。我無法弄清楚為什麼這僅在一周內不起作用。這是輸出

D20220320,S2927,977,1 -- correct

D20220320,S2927,977,1 -- incorrect 

D20220321,S2927,977,1 -- incorrect

D20220322,S2927,977,1 -- incorrect

D20220323,S2927,977,1 -- incorrect

D20220324,S2927,977,1 -- incorrect

D20220325,S2927,977,1 -- incorrect

D20220326,S2927,977,1 -- incorrect

D20220328,S2927,977,1 -- correct

這裡使用的邏輯是:

   BEGIN {
       OFS = FS = ","
}

{
       t = mktime(sprintf("%4d %.2d %.2d 00 00 00",
               substr($1,2,4),
               substr($1,6,2),
               substr($1,8,2)));

       $1 = substr($1,1,1) strftime("%Y%m%d", t - 7*24*60*60)

       print
}

您的計算是在當地時間完成的,您會受到 3 月 27 日切換到夏令時的影響。

要改為使用 UTC 時間進行計算(Unix 時間戳不是本地時間),請使用最新版本的 GNU awk,確保將額外的1作為最後一個參數傳遞給mktime()

t = mktime(sprintf("%4d %.2d %.2d 00 00 00",
       substr($1,2,4),
       substr($1,6,2),
       substr($1,8,2)), 1);

這是GNU版本 4.2.0+awk中可用的 GNU 擴展。awk

作為替代方案,您可以避免使用午夜 (UTC) 附近的時間作為您一天中的參考時間:

t = mktime(sprintf("%4d %.2d %.2d 12 00 00",
       substr($1,2,4),
       substr($1,6,2),
       substr($1,8,2)));

這將使它在較舊的 GNUawk實現和任何其他awk具有所需功能的實現中工作。

另一種選擇是使腳本以更改的本地時區執行:

TZ=UTC awk -f script.awk inputfile

這會將TZ環境變數設置UTC為執行awk腳本,這會改變mktime()和相關函式使用的時區。

引用自:https://unix.stackexchange.com/questions/675949