Autor Beitrag
hRb
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 169
Erhaltene Danke: 9



BeitragVerfasst: Mo 29.04.19 20:49 
Hallo zusammen,
benötige etwas Hilfe im Sprachenwirrwarr Datum - Änderungsdatum - Aufnahmedatum - Erstelldatum. Diese vier Begriffe zeigt der MS-Explorer in unterschiedlichen Situationen unter Details.
Wie an anderer Stelle erwähnt, erstelle ich ein eigenes kl. Programm zum Ändern des Dateidatums. Dieses Programm funktioniert wunschgemäß, bis ich plötzlich Abweichungen in der Anzeige gegenüber dem MS-Explorer erkannte. Stelle unter WIN10 folgende Eigenschaft fest (die verwirrt):

Ändere ich das Dateidatum mit der Funktion
FileSetDate(FileHandle,dt.Time )  // dt = tSearchRec
so funktioniert dies bei allen nicht-grafik-Dateitypen, wie pas, txt, aber auch bei einigen Grafik-typen wie bmp, ico. Genauer gesagt: das neue Datum stimmt mit der Anzeige im MS-Explorer überein. Dort erscheint als Überschrift "Änderungsdatum".

Bei Verzeichnissen die nur jpg-Dateien enthalten, wechselt die Überschrift im Explorer auf "Datum" und unter Details wird erkennbar, dass vorrangig - sofern vorhanden -das Aufnahmedatum und nicht das Änderungsdatum angezeigt wird. Dies führt logischer weise zu abweichenden Anzeigen (siehe Anlage).

Wünschte ich gleiche Anzeige zwischen meinem (Pascal-)Programmen und dem MS-Explorer, müsste ich nicht nur das Filedatum (Änderungsdatum), sondern auch das Aufnahmedatum ident ändern. Daneben gibt es als Drittes noch das "Erstelldatum".

1. Ist bekannt warum MS bei Bildern das Aufnahemedatum nicht das Pascal-Filedatum anzeigt?
2. Wer kann sprachlich aufklären? Ist Aufnahmedatum = Exif-Datum und was ist dann das Erstelldatum?
3. Mit welcher Pascal-Funktion kann ich bei Bildern das "Aufnahmedatum" ändern? In TSearchRec kann ich keinen Ansatz finden.
4. Gibt es ggf. eine Pascal-Funktion die beides in einem Schritt ändert - ohne Fehler zu liefern wenn die zu ändernde Datei keine Bilddatei ist?
Wäre dankbar für mehr Klarheit und Lösungsvorschläge. hRb
Einloggen, um Attachments anzusehen!
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 29.04.19 22:57 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Holgerx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 55
Erhaltene Danke: 22

Win95 - Win8.1 / MSServer2000 - MSServer2012
Delphi 6pro / XE4
BeitragVerfasst: Di 30.04.19 05:30 
Hmm..

Dir ist bewusst, das Erstelldatum / Änderungsdatum eine Fileinformation im Dateissystem ist, jedoch Aufnahmedatum eine 'zusätzliche' Information aus der Datei selber?

Der Explorer holt z.B. bei Ordnern mit reinen Bild Dateien eben aus diesen die eingebetteten zusätzlichen Informationen, wie z.B: Aufnahmedatum oder Auflösung.
Er 'meint' intelligent zu sein, auch wenn der Benutzer eigentlich das Filedatum haben möchte.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 169
Erhaltene Danke: 9



BeitragVerfasst: Di 30.04.19 22:47 
Hallo Frühlingsrolle, Holgerx
zunächst danke für die Antworten. Habe vermutlich zu viele Fragen auf einmal gestellt - auch mit falschen Annahmen. Zur Aufklärung:
1. Das Wort "Pascal-Filedatum" habe ich gewählt, weil ich von der Hilfe nur das Filedatum aus TSearchRec.Time kenne. Hatte in meinen Fragen unterstellt (nicht ausgeschlossen), dass es in neueren MS-Betriebssystemen (WIN10) weitere "Datums-Erweiterungen" gibt, um zu erkennen, ob eine Datei nachträglich nochmals geöffnet/geändert wurde. In der Pascal-Hilfe konnte ich nichts finden.
Nach der Antwort von Holgers zu schließen gibt es nur EIN Filedatum. Erstell- oder Aufnahmedatum sind offenbar Parameter in den Bilddateien (jpg).
2. Das Wort "letzte Änderung" in der StringGridtabelle meines Programms (gemäß dem gezeigten Bild) ist eine von mir gewählte Überschrift; hat also keine verbindliche Aussagekraft und nichts mit Microsoft-Vokabular zu tun.
3. Was mich irritierte und nicht verstehe ist, dass Microsoft bei Bilddateien einen Sonderweg geht und nicht das "offizielle" (normale) Filedatum anzeigt. Sowohl der TotalCommander als auch der FreeCommander verhält sich hier anders. Dieses "Sonderverhalten" im Explorer ist m.E sehr ärgerlich und schafft die Probleme. Da bei Windows-Nutzern die Verwendung des MS-Explorer überwiegt, ist eine File-Datumsänderung bei Bilddateien ungeeignet, um im Verzeichnis eine neue Bild-Sortierung zu erreichen; es sei denn, man ändert auch das Datum im jpg-Bildheader. Das wäre mein Ziel.

Meine Frage ist somit neu: hat jemand eine fertige Befehlsfolge um das Exif-Datum in Bildern zu ändern (ggf. nur jpg). Unter
www.waimea.de/downlo...EXIF-Datenformat.pdf
wird die jpg-Struktur beschrieben, erfordert aber eine umfassende Datei-Analyse. Aus dem pdf-Dokument geht hervor, dass der jpg-Header sich teilweise des tif-Headers bedient.

Um nochmals deutlich zu machen, dass hinter meinen Fragen eine konkrete Aufgabe besteht, hier nochmals das Problem:
Ich erhalte für DIA-Shows von mehreren Personen Bilder (von unterschiedlichen Kameratypen oder Handys). Beim Zusammenfügen der Bilder ist der Alphaname zur Sortierung demzufolge ungeeignet. Bleibt das Datum. Selbst wenn auch die Kamerazeiten häufig von einander abweichen, ist die Differenzeit zur einer angenommenenn Basiszeit eine Konstante. Wird diese ermittelt, können alle Bild-Zeiten dieser Kamera korrigiert werden. Soviel nochmals zur Aufgabe. Eigentlich eine Anforderung, die andere schon gelöst haben sollten. Insoweit hoffe ich noch auf hilfreichen Code.
Nachtrag: sehe gerade: Frühlingsrolle schreibt:
Zitat:
Die Funktion SetFileTime() kann mehr als ein Datum ändern.

Gibt es da ein Codebeispiel und löst dieser Funktion mein Problem? Woher weiß die Funktion, wenn sie nur das Handle hat, dass es sich um eine Bilddatei handelt?
Gruß hRb
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 01.05.19 00:38 
- Nachträglich durch die Entwickler-Ecke gelöscht -
icho2099
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 80
Erhaltene Danke: 8

WIN XP, WIN 7, WIN 10
Delphi 6 Prof, Delphi 2005
BeitragVerfasst: Mi 01.05.19 08:57 
Holgerx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 55
Erhaltene Danke: 22

Win95 - Win8.1 / MSServer2000 - MSServer2012
Delphi 6pro / XE4
BeitragVerfasst: Mi 01.05.19 09:20 
Hmm..

Im FileSystem von Windows hat jede Datei, unabhängig vom Inhalt die 3 Zeitstempel 'CreationTime', 'LastAccessTime' und 'LastWriteTime'.

Diese werden von TotalCommander oder FreeCommander angezeigt und auch immer vom Explorer, wenn dieser (umständlich) umkonfiguriert wurde.

Leider geht hier Microsoft mit seinem Explorer einen anderen Weg:
Sie meinen, anhand des Dateitypes (des Verzeichnisinhaltes) andere Infos anzuzeigen.
Z.B. bei Bildern Informationen aus den EXIF Daten oder bei Videos deren Auflösung.
(Wie man das dem Explorer abgewöhnen kann, kannst Du im Internet googlen)

Wenn Du nun nur mit den 3 FileTimes arbeiten möchtest, dann kannst Du diese über dein SearchRec auslesen.
Die Zeitangaben befinden sich dort unter

TSearchRec.FindData.ftCreationTime
TSearchRec.FindData.ftLastAccessTime
TSearchRec.FindData.ftLastWriteTime

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
function FileTimeToDateTime(AFileTime : TFileTime): TDateTime;
var
  SystemTime: TSystemTime;
  LocalTime : TFileTime;
begin
  FileTimeToLocalFileTime(AFileTime,LocalTime);
  FileTimeToSystemTime(LocalTime,SystemTime);
  result := SystemTimeToDateTime(SystemTime);
end;

procedure TForm1.ReadFileTime(AFileName: string);
var
  SR: TSearchRec;
  tmpDateTime : TDateTime;
begin
  Edit1.Text := AFileName;
  if FindFirst(AFileName,faAnyFile,SR) = 0 then begin

    tmpDateTime := FileTimeToDateTime(SR.FindData.ftCreationTime);
    DateTimePicker_DateCreation.Date := DateOf(tmpDateTime);
    DateTimePicker_TimeCreation.Time := TimeOf(tmpDateTime);

    tmpDateTime := FileTimeToDateTime(SR.FindData.ftLastAccessTime);
    DateTimePicker_DateAccess.Date := DateOf(tmpDateTime);
    DateTimePicker_TimeAccess.Time := TimeOf(tmpDateTime);

    tmpDateTime := FileTimeToDateTime(SR.FindData.ftLastWriteTime);
    DateTimePicker_DateChange.Date := DateOf(tmpDateTime);
    DateTimePicker_TimeChange.Time := TimeOf(tmpDateTime);
  end;
  FindClose(SR);
end;



Zum Ändern kannst Du dann das erwähnte SetFileTime verwenden. Hiermit kannst Du einen oder auch alle Werte gleichzeitig ändern.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
const
  // 24 * 60 * 60 * 1000 * 1000 * 10;
  CentiMicroSecondsPerDay = 864000000000.0;
  FileTimeStart = -109205;  // 1601-01-01T00:00:00

function DateTimeToLocalFileTime(Value: TDateTime): TFileTime;
begin
  Int64(Result) := Round((Value - FileTimeStart) *
                   CentiMicroSecondsPerDay);
end;

function LocalFileTimeToDateTime(Value: TFileTime): TDateTime;
begin
  Result := (Int64(Value) / CentiMicroSecondsPerDay) + FileTimeStart;
end;



type
  // indicates the file time to set, used by SetFileTimesHelper
  // and SetDirTimesHelper
  TFileTimes = (ftLastAccess, ftLastWrite, ftCreation);

function SetFileTimesHelper(const FileName: String;
                            const DateTime: TDateTime;
                            Times: TFileTimes;
                            IsUTCBased: Boolean): Boolean;
var
  Handle: THandle;
  FileTime: TFileTime;
  LocalFileTime: TFileTime;
begin
  Result := False;

  Handle := CreateFile(PChar(FileName), GENERIC_WRITE, FILE_SHARE_READ,
                       nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);

  if Handle <> INVALID_HANDLE_VALUE then
  try
    LocalFileTime := DateTimeToLocalFileTime(DateTime);
    if IsUTCBased then begin
      FileTime := LocalFileTime;
      Result := True;
    end else begin
      Result := LocalFileTimeToFileTime(LocalFileTime, FileTime);
    end;
    if Result then begin
      case Times of
        ftLastAccess: Result := SetFileTime(Handle, nil, @FileTime, nil);
        ftLastWrite:  Result := SetFileTime(Handle, nilnil, @FileTime);
        ftCreation:   Result := SetFileTime(Handle, @FileTime, nilnil);
      else
        Result := False;
      end;
    end;
  finally
    CloseHandle(Handle);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  tmpDateTime : TDateTime;
begin
  tmpDateTime := DateOf(DateTimePicker_DateAccess.Date) + TimeOf(DateTimePicker_TimeAccess.Time);
  SetFileTimesHelper(Edit1.Text,tmpDateTime,ftLastAccess, false);

  tmpDateTime := DateOf(DateTimePicker_DateChange.Date) + TimeOf(DateTimePicker_TimeChange.Time);
  SetFileTimesHelper(Edit1.Text,tmpDateTime,ftLastWrite, false);

  tmpDateTime := DateOf(DateTimePicker_DateCreation.Date) + TimeOf(DateTimePicker_TimeCreation.Time);
  SetFileTimesHelper(Edit1.Text,tmpDateTime,ftCreation, false);
end;


(Den Source habe ich aus einem alten Testprogramm, und dieser stammt teilweise aus diversen Quellen des Internets ;) )


Ich würde Dir nicht raten, die Exif-Informationen zu verändern, das könnte schwierig werden, da auch hier leider die diversen Kamerahersteller unterschiedliche Wege gehen. Auch sollten diese fest zum Foto gehörenden Informationen nicht durch dich zur Verwendung für eine Dia-Show geändert werden, da der User diese vielleicht noch in Zukunft verwenden will.

Wenn diese Dateien auf dein Laufwerk kopiert wurden, dann sollten die FileTimes eigentlich bleiben.
Nutze besser diese, die kannst Du ändern und sie werden auch von Windows selber teilweise geändert.
icho2099
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 80
Erhaltene Danke: 8

WIN XP, WIN 7, WIN 10
Delphi 6 Prof, Delphi 2005
BeitragVerfasst: Do 02.05.19 07:46 
Wenn man nun aber die Fotos in eine Reihenfolge bringen möchte, die der realen Zeit der Aufnahme entspricht, dann helfen die OS Zeitstempel nicht. Die geben ja nur Auskunft darüber wann die Fotos im Album abgelegt und/oder letztmalig verändert wurden.
Der Bezug zur Realzeit kann nur über den Inhalt des Fotos selber hergestellt werden, i.d.R. sind dazu die Gangabweichungen der Aufnahmegeräte zu kennen und zu berücksichtigen.
Aus meiner Sicht führt da kein Weg an den Exif-Daten vorbei, wobei ich zustimme diese nicht zu verändern sondern nur zu lesen.
Für die Zielsortierung kann dann einer der OS Stempel manipuliert werden. Ich würde auch das Korrektiv speichern, zB im Dateiname.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 169
Erhaltene Danke: 9



BeitragVerfasst: Fr 03.05.19 17:03 
Zwischennachricht,
Hallo zusammen. Allen vielen Dank. Ihr seid super! Habe ein kleines Testprogramm erstellt: funktioniert bestens!
Werde es in Kürze posten. Wenn alle Zeiten identisch sein sollen, geht es vermutlich noch etwas schlanker.
Allerdings bleibt der Hinweis von icho2099 ebenso korrekt: die Änderung der 3 Zeiten hilft nicht das grundsätzlich Problem mit dem MS-Explorer zu beheben ( da Exif-Anzeige). Melde mich nochmals... (Enkelpflichten rufen)
Gruß hRb
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18704
Erhaltene Danke: 1621

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 04.05.19 08:12 
Das Verhalten ist im Windows Explorer schon korrekt. Wenn man die Spalte Datum anzeigt (was der Standard ist), werden nach Möglichkeit die Daten dafür aus der Datei ausgelesen sofern das Dateiformat dies unterstützt.

Wenn man das reine Änderungsdatum möchte, dann muss man auch im Kontextmenü der Überschriften die entsprechende Spalte auswählen, ebenso wie Aufnahmedatum usw.:

DatumWindowsExplorer

Die meisten Benutzer dürfte das Aufnahmedatum allerdings mehr interessieren als das Änderungsdatum im Dateisystem (mich eingeschlossen) und insofern ist die Standardeinstellung schon gut so, aber man kann sie eben jederzeit ändern.
Einloggen, um Attachments anzusehen!
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 169
Erhaltene Danke: 9



BeitragVerfasst: Mi 08.05.19 00:18 
Hallo zusammen,
als Anlage (zip-Datei) habe ich ein kleines lauffähiges Programm angefügt (compiliert mit Berlin 10.2). Hiermit lassen sich:
- die drei Filedaten getrennt ändern
- mit einem Klick alle Filedaten ident setzen
- nur SearchRec.Time ändern
Code-Grundlage bilden die Funktionen und Prozeduren von Holgerx (hierfür Dank). Raffiniert die Befehlsfolge
ausblenden Delphi-Quelltext
1:
2:
3:
  Handle := CreateFile(PChar(FileName), GENERIC_WRITE, FILE_SHARE_READ,
                       nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
  if Handle <> INVALID_HANDLE_VALUE then

Hätte so etwas nie formuliert!
An meinem Programm stelle ich bei den verschiedenen Zeiten etwas eigenartiges fest und habe dafür keine Erklärung:
1. Dass das SearchRec.Time auf Grund der 32-Bit-Darstellung die Zeit auf gerade Sekunden rundet, ist bekannt. Was mir nicht klar ist, warum SearchRec.Time bei geraden Sekunden gegenüber den anderen 3 Zeiten immer 2 Sekunden abweicht (falsch anzeigt). Effekt wird erkennbar wenn man die Zeiten ändert mittels "SetLastWriteTime". Danach zeigt FileTime = SearchRec.Time zwei Sekunden zuviel an.
2. jaenicke findet das Verhalten im Windows Explorer korrekt. Ich kann dem nicht zustimmen, weil der Explorer automatisch zwischen "Datum" und "Änderungsdatum" hin und herschaltet - je nach Dateityp. Da unter Ansicht ja alle Parameter vom Anwender zu- oder weggeschaltet werden können, besteht m.E. kein Anlass zum switchen. Die Voreinstellung, die man je explizit für alle Ordner einstellen kann, sollte in allen Verzeichnissen ident sein.
3. Bin zwar mit den verschiedenen Zeiten ein wenig schlauer, leider bleibt mein Problem mit dem Exif-Datum bestehen. Mal sehen, ob ich hier noch etwas tue. Solange ich nicht zwischen meinem Programm und dem Explorer hin und herschalte und die Werte vergleiche, ist ja alles Ok.
hRb
Einloggen, um Attachments anzusehen!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18704
Erhaltene Danke: 1621

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 08.05.19 05:37 
Wenn es nur um deinen PC geht... Es könnte schon reichen den Default Wert (@) unter diesem Registryzweig zu deaktivieren, sprich irgendwie zu ändern:
HKLM\Software\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.jpg

Dann sollte der Windows Explorer die Exif Daten nicht mehr lesen können.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 169
Erhaltene Danke: 9



BeitragVerfasst: Fr 17.05.19 11:52 
Danke für alle Beiträge. Schließe Thema hiermit ab.
hRb