AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Darstellung von Datum und Uhrzeit in Programmen
Tutorial durchsuchen
Ansicht
Themen-Optionen

Darstellung von Datum und Uhrzeit in Programmen

Ein Tutorial von Brüggendiek · begonnen am 29. Mär 2005
Antwort Antwort
Brüggendiek
Registriert seit: 13. Dez 2002
Hallo!

Da die Formatierung von Datum und Uhrzeit immer wieder zu Problemen und Ärgernissen führt, habe ich hier mal einige Überlegungen dazu zusammengestellt.

Hinweis: Diese Anleitung ist nicht speziell für Delphi. Es werden Delphi-Routinen verwendet, aber das Prinzip gilt für alle Programmiersprachen.

Es sind auch keine Code-Beispiele enthalten. Die Anwendung der einzelnen Routinen ist ja in der Online-Hilfe beschrieben und die hier angeführten Dinge benutzen nur absolute Grundlagen.


Die Darstellung von Datum und teilweise auch Uhrzeit gehört zu den schwierigsten Problemen der Datenverarbeitung.

Bei der Zeit hat man allenfalls das Problem mit 12 oder 24-Stunden, aber leider gibt es beim Datum regional unterschiedliche Darstellungen der drei Teile Jahr, Monat und Tag. Das große Delphi-Treffen findet am 2. April 2005 statt - ich benutze diese Datum hier mal als Beispiel.
Zusätzlich gibt es Probleme, wenn die Jahreszahl nur zweistellig gespeichert wird.
  • Bekannte Formate sind:
  • Deutschland: Tag.Monat.Jahr, also 02.04.2005 bzw. 02.04.05.
  • USA: Monat-Tag-Jahr, also 04-02-2005 bzw. 04.02.05.
  • ISO: Jahr-Monat-Tag, also 2005-04-02 bzw. 05-04-02.
Eventuell kann auch noch die führende Null bei Tag und Monat entfallen.

Das ISO-Format wird übrigens in Schweden verwendet, während in Deutschland nach neuester Norm auch das ISO-Format angewendet werden soll - dies ist allerdings nicht weit verbreitet.


Zunächst ergibt sich bei Datumsangaben nun ein Sortierproblem.
Ein Mensch, der z.B. Karteikarten nach Datum sortieren soll, wird sein gewohntes Format anwenden. Für einen Rechner sind das jedoch alles nur Zeichenfolgen und das Sortieren liefert ohne passende Routinen dann unschöne Ergebnisse.
Ein Beispiel für nicht anpassbare Sortierung wäre eine Speicherung von Dateien mit Datum im Dateinamen. Die Sortierfunktion für Dateien im Ordner kennt nur die ANSI-Reihenfolge.
  • Die Folgen einer ANSI (Buchstaben)-Sortierung sind:
  • Deutsches Format: Es werden zunächst alle 1. Januar, dann alle 1. Februar usw. bis alle 1. Dezember nach aufsteigenden Jahren sortiert, dann folgen alle 2. Januar usw. Reichlich unübersichtlich!
  • US-Format: Hier werden alle 1. Januar, dann alle 2. Januar usw. einsortiert. Hier stimmt wenigstens die Reihenfolge von Tag und Monat, aber alle gleichen Tage der einzelnen Jahre folgen direkt aufeinander. Das ist natürlich für einen Geburtstagskalender optimal, aber sonst auch nicht unbedingt brauchbar.
  • ISO-Format: Da hier die Felder in Reihenfolge ihrer Wertigkeit stehen, stimmt (zumindest bei einer Darstellung mit führenden Nullen) die Reihenfolge ohne spezielle Sortierverfahren. Deshalb ist dieses Format für eine Sortierung bestens geeignet.

Bei MS-DOS bis Version 6 gab es keine Einstellmöglichkeit für die Datumsdarstellung. Man konnte nur einen Ländercode eingeben (001 für USA, 049 für Deutschland, 046 für Schweden etc., entsprechend der Ländervorwahlen beim Telefon). Programme sollten diesen Ländercode für Datum und ggf. die Dialogsprache beachten. Die Sprache war aber in den wenigsten Programmen implementiert, so das meine Einstellung "Schweden" (wegen ISO-Datum) nur ganz selten zu schwedischen Texten führte.

Unter MS-DOS 7 mit der grafischen Oberfläche Windows 4 (Handelsnamen: Windows 95, Windows 98, Windows ME) und unter Windows (NT/2000/XP) kann man nun das Datumsformat frei einstellen. Vorsicht: wenn man das Datum bei einem deutschen Windows so einstellt:
Code:
T.M.JJJJ; JJJJ-MM-TT
findet das Treffen statt am
Code:
2.4.2005; 2005-04-02
und sprengt damit möglicherweise das Datumsfeld in einem Programm!
Einen solchen Datumsstring kann man außerdem bei mir (Delphi 5 Standard auf Win98) mit StrToDate nicht mehr konvertieren - es erscheint die Fehlermeldung: "2.4.2005; 2005-04-02 ist kein gültiges Datum".


Die interne Speicherung von Datum und Uhrzeit als irgendwie linearen Wert (Delphi: Double-Wert mit Vorkomma als Tage seit 1899-12-30, UNIX: Tage seit 1970-01-01) bereitet gegenüber einer diskreten Darstellung (Record mit Tag, Monat und Jahr) noch das Problem, das es kein ungültiges Datum gibt. Bei einem Record kann man alle 3 Werte auf 0 setzen, wenn kein Datum eingegeben wurde. Was aber soll man zuweisen, wenn man ein Delphi- oder UNIX-Datum verwendet?
Da hat man im DF ja schlechte Erfahrungen mit: Wer keinen Geburtstag eingegeben hatte, stand in der Datenbank mit Geburtstag "0" - mit der Folge, daß am 2005-01-01 eine große Anzahl von Benutzern angeblich Geburtstag hatten! Da die Liste in Standardeinstellung auf jeder Seite auftauchte, hatten Modem-User ein Problem

Bei der Uhrzeit ergibt sich auch bei Records ein Problem, denn 00:00 ist ja gültig (im Gegensatz zum Datum 0000-00-00). Bei mir wird dann 24:60 als ungültige Uhrzeit verwendet.


Wie stelle ich ein Datum am Sinnvollsten dar?

  • Prinzipiell gibt es zwei Möglichkeiten zur Verwendung einer Datumsangabe:
  • Für den Benutzer,
  • Für das Programm.

Für den Benutzer gibt es nur eine sinnvolle Möglichkeit: man verwendet die Benutzereinstellung im System, denn so erwartet man das von den Programmen.
Delphi hilft uns da ja mit DateToStr bei der Ausgabe. Wie schon erwähnt, gibt es jedoch Probleme bei StrToDate, wenn der Benutzer ein ungewöhnliches Format eingestellt hat. Da muss man dann eventuell das Ganze manuell umwandeln.
Will man eine Datumseingabe schreiben, sollte man vorsichtshalber mit solchen Fallen rechnen und entsprechend reagieren.


Für das Programm kann es auch nur eine Möglichkeit geben, mit Datumswerten umzugehen: eine feste, vom Programmierer definierte Darstellung!
Dabei ist wegen der Sortiermöglichkeit auf Stringebene das ISO-Format sehr gut geeignet.
Wer die Systemeinstellungen verwendet, bekommt spätestens dann Probleme, wenn die Datendatei auf einem Rechner mit anderer Einstellung bearbeitet werden soll oder der Benutzer ein anderes Format einstellt.
Für die Ausgabe von Datumswerten stehen mit DateTimeToString und FormatDateTime Routinen zur Verfügung, die ein Datum in beliebiger Darstellung ausgeben können. Für die Rückumwandlung muss man jedoch den Datumsstring aufteilen, das Ganze mit StrToInt in drei Zahlen konvertieren und dann. mit EncodeDate in ein Delphi-Datum umwandeln.


Ein Riesen-Problem entsteht natürlich, wenn das Datum vom Programm weiterverarbeitet werden soll, aber auch für den Benutzer sichtbar ist. Das ist regelmäßig der Fall, wenn das Datum Teil eines Dateinamens ist.
Mehrere Punkte im Dateinamen sind erlaubt, man sollte das jedoch vermeiden. Es soll Programme geben, die beim Auffinden solcher Dateinamen eine Viren-Warnung ausgeben (wie war das damals noch mit "Loveletter.txt.vbs"?), also sollte man besser "-" statt Punkt verwenden.

Man kann ja in diesem Fall im Auswahldialog zum Öffnen der Datei das Datum im eingestellten Format anbieten, aber auf der Platte muss ein einheitliches Format gewählt werden! Wenn man mit zweistelliger Jahreszahl arbeitet, kann "05-04-02" ja je nach Einstellung der 5.April 2002, der 4.Mai 2002 oder der 2.April 2005 sein - man sollte da möglichst die Dateinamen nicht verwechseln.
Hat der Benutzer am 5.April 2002 eine Datei im deutschen Format gespeichert und stellt nun auf ISO um, ist am 2.April 2005 die Datei schon vorhanden bzw. es wird eine alte Datei überschrieben.

Man kann allerdings auch "benutzerfreundlich" programmieren in dem Sinne: Der Benutzer soll so freundlich sein, das Datumsformat nie zu ändern! Der Gipfel der Benutzerfreundlichkeit ist es dann, in der Anleitung des Programms nicht darauf hinzuweisen
  • Das Datumsformat im Programm einzustellen, kann auch keine Lösung sein:
  • Bei Änderungen müssen alle Dateien umbenannt werden
  • Datensicherungen enthalten nach Änderungen falsche Dateinamen
  • Austausch zwischen verschiedenen Benutzern ist nicht möglich

Fazit: Manchmal muss der Benutzer eben so freundlich sein, auf Einstellmöglichkeiten zu verzichten!


Besonders schlimm wird es, wenn das Format extern vorgegeben ist! So enthält der deutsche Personalausweis das Geburtsdatum und das Ablaufdatum in der Darstellung "JJMMDD". Mir ist ein Programm untergekommen, bei dem die Stringgteile offensichtlich auf "DD.MM.JJ" umgestellt und dann mit StrToDate in ein Delphi-Datum umgewandelt wurde. Das klappte dann bei mir irgendwie nicht so ganz - mein Datumsformat ist ISO und der bis 2008 gültige Ausweis war angeblich bereits abgelaufen!


Hoffentlich konnte ich mit diesem Text ein paar Denkanstöße geben.

Gruß

Dietmar Brüggendiek
Die 6 Probleme des Programmierers: 1. dauert das länger, als man 2. glaubt, 3. geht das nicht so, wie man sich das 4. schlau überlegt hat, und 5. sitzt der Fehler da, wo man ihn 6. zuletzt sucht
 
Antwort Antwort


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 02:57 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz