日付変換が期待どおりに機能しません。

日付変換が期待どおりに機能しません。

次の形式のレコードを含むファイルがあります。

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
}

ベストアンサー1

あなたの計算は現地時間で行われ、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)));

これにより、以前のGNU実装と必要な機能を備えた他の実装awkで機能することができます。awk

別のオプションは、変更されたローカルタイムゾーンでスクリプトを実行することです。

TZ=UTC awk -f script.awk inputfile

これにより、実行スクリプトにTZ環境変数が設定され、関連機能で使用されるタイムゾーンが変更されます。UTCawkmktime()

おすすめ記事