AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls TZipfile - ModifiedDateTime unter Linux und MAC richtig auslesen
Thema durchsuchen
Ansicht
Themen-Optionen

TZipfile - ModifiedDateTime unter Linux und MAC richtig auslesen

Ein Thema von Harry Stahl · begonnen am 12. Dez 2021 · letzter Beitrag vom 12. Dez 2021
 
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.677 Beiträge
 
Delphi 12 Athens
 
#8

AW: TZipfile - ModifiedDateTime unter Linux und MAC falsch

  Alt 12. Dez 2021, 15:20
Wieso soll das ein Fehler von TZipFile sein? Das Feld ModifiedDateTime steht als UInt32 im ZipHeader. Das Problem ist die Umwandlung über FileDateToDateTime und das hat gar nichts mit TZipFile zu tun.

Die Zip-Specs beschreiben diese vier Bytes folgendermaßen:
Zitat:
4.4.6 date and time fields: (2 bytes each)

The date and time are encoded in standard MS-DOS format.
If input came from standard input, the date and time are
those at which compression was started for this data.
If encrypting the central directory and general purpose bit
flag 13 is set indicating masking, the value stored in the
Local Header will be zero. MS-DOS time format is different
from more commonly used computer time formats such as
UTC. For example, MS-DOS uses year values relative to 1980
and 2 second precision.
Zufälligerweise (na ja, nicht ganz zufällig) macht FileDateToDateTime das unter Windows richtig, aber sonst eben nicht, da dort ein FileDate halt anders codiert ist. TZipFile schreibt aber das DOS-Format vor und das ist immerhin auch das, was Zipper unter Mac oder Linux da reinschreiben. Das Problem ist also nicht, dass TZipFile da was falsch macht, vielmehr muss der Programmierer eine geeignete, plattformunabhängige Umwandlungsmethode verwenden.

Der beschriebene Workaround ist zwar funktionsfähig, sollte aber m.E. anders heißen und ohne damit IFNDEF Windows auskommen:
Delphi-Quellcode:
function ZipFileDateToDateTime(FileDate: UInt32): TDateTime;
begin
  Result :=
    EncodeDate(
      LongRec(FileDate).Hi shr 9 + 1980,
      LongRec(FileDate).Hi shr 5 and 15,
      LongRec(FileDate).Hi and 31) +
    EncodeTime(
      LongRec(FileDate).Lo shr 11,
      LongRec(FileDate).Lo shr 5 and 63,
      LongRec(FileDate).Lo and 31 shl 1, 0);
end;
Ich glaube auch nicht, dass hier die unterschiedlichen Längen eines Longint die Ursache sind. Vielmehr wird bei Unix die Anzahl der Sekunden seit 1. Januar 1970, 00:00 Uhr UTC in dem Wert gespeichert, während bei der MS-DOS Version die einzelnen Datums- und Zeitanteile als Bits abgelegt sind (siehe DosDateTimeToFileTime). Daraus wird klar, dass die Umwandlung eines MS-DOS Zeitstempels mit Unix-Methoden nicht das erwartete Ergebnis bringen kann.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz