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.