Terminverschiebung funktioniert nicht wie erwartet

Terminverschiebung funktioniert nicht wie erwartet

Ich habe eine Datei mit Datensätzen in diesem Format:

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

Nach der Anwendung der Transformation, um diese Daten auf 7 Tage in die Vergangenheit zu verschieben, funktioniert es jedoch nicht für Daten vom 28. März bis 3. April. Dieselbe Codelogik funktioniert jedoch am 27. März und 4. April einwandfrei. Ich kann nicht verstehen, warum dies nur für eine Woche nicht funktioniert. Dies ist die Ausgabe

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

Die hier verwendete Logik ist:

    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
}

Antwort1

Ihre Berechnungen erfolgen in Ortszeit und Sie sind von der Umstellung auf die Sommerzeit am 27. März betroffen.

Um die Berechnung stattdessen in UTC-Zeit durchzuführen (Unix-Zeitstempel geben keine Ortszeit an) und eine aktuelle Version von GNU zu verwenden awk, achten Sie darauf, dass Sie 1als letztes Argument ein zusätzliches Argument an übergeben mktime():

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

Dies ist eine GNU- awkErweiterung, die in GNU- awkVersion 4.2.0+ verfügbar ist.

Alternativ können Sie auch vermeiden, eine Zeit um Mitternacht (UTC) als Referenztageszeit zu verwenden:

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

awkDadurch würde es in älteren GNU- Implementierungen und in allen anderen Implementierungen funktionieren, awkdie über die erforderlichen Funktionen verfügen.

Eine weitere Alternative besteht darin, das Skript mit einer geänderten lokalen Zeitzone auszuführen:

TZ=UTC awk -f script.awk inputfile

Dadurch wird die TZUmgebungsvariable UTCfür die Ausführung des Skripts festgelegt, wodurch die von den und verwandten Funktionen awkverwendete Zeitzone geändert wird .mktime()

Antwort2

Verwenden von Raku (früher bekannt als Perl_6)

raku -pe 's/^ D <( (\d**4)(\d**2)(\d**2) )> \, /{ "$0-$1-$2".Date.earlier(:7days).Str.subst("-", :g); }/;'

Beispiel-Eingabe (Leerzeilen entfernt):

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

Beispielausgabe:

D20220320,S2927,977,1
D20220321,S2927,977,1
D20220322,S2927,977,1
D20220323,S2927,977,1
D20220324,S2927,977,1
D20220325,S2927,977,1
D20220326,S2927,977,1
D20220327,S2927,977,1
D20220328,S2927,977,1

Kurz gesagt werden Rakus zeilenweise (Autoprinting-) -peFlags in Verbindung mit dem bekannten s///Operator verwendet. Ziffern werden in Übereinstimmungsvariablen $0, $1und $2mit Klammern erfasst, und Erfassungsmarker <( … )>werden verwendet, um alle anderen Elemente der Übereinstimmung zu löschen.

Beim Ersetzen führt Raku Code innerhalb eines { … }Blocks aus. Die $0, $1, und $2Captures werden mit entsprechenden Bindestrichen ( -) in Zeichenfolgen umgewandelt, und diese Zeichenfolge wird als DateObjekt erkannt, für das die earlier(:7days)Methode aufgerufen werden kann. [Hinweis: Einige Benutzer finden möglicherweise „writing“ earlier(days => 7)als vertrautere Syntax – beide Formen funktionieren]. Sobald das DateObjekt 7 Tage zurückgesetzt wurde, wird es Strmit „-ing“ umgewandelt und substverwendet, um die Bindestriche ( -) in der Rückgabe zu entfernen.

https://docs.raku.org/routine/Date
https://docs.raku.org/routine/Dateish
https://raku.org

verwandte Informationen