Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   0.0 ist kein gültiger Zeitstempel (https://www.delphipraxis.net/162030-0-0-ist-kein-gueltiger-zeitstempel.html)

Angel4585 2. Aug 2011 15:13

Datenbank: BDE • Version: 5.2.xyz • Zugriff über: Delphi Std DB Komponenten

0.0 ist kein gültiger Zeitstempel
 
Ich hab ne leere Tabelle mit ein paar Feldern. Eins davon ein Datumsfeld(Nicht DateTime, sondern Date)
Da ich jetz nix besseres gefunden hab, sprich ich das Feld über .AsDateTime an um den Wert auf Now zu setzen.
Dummerweise hab ich jetz als Datum den 15.8.11572 drin und bekomm beim Auslesen als Datetime eben die Meldung 0.0 ist kein gültiger Zeitstempel.
Wenn ich das Feld auf DateTime setze geht es.

Was für Werte erwartet denn so ein Date-Feld? :cyclops:

DeddyH 2. Aug 2011 15:18

AW: 0.0 ist kein gültiger Zeitstempel
 
Welche DB ist das denn? Paradox?

QuickAndDirty 2. Aug 2011 17:40

AW: 0.0 ist kein gültiger Zeitstempel
 
Zitat:

Zitat von Angel4585 (Beitrag 1114759)
Ich hab ne leere Tabelle mit ein paar Feldern. Eins davon ein Datumsfeld(Nicht DateTime, sondern Date)
Da ich jetz nix besseres gefunden hab, sprich ich das Feld über .AsDateTime an um den Wert auf Now zu setzen.
Dummerweise hab ich jetz als Datum den 15.8.11572 drin und bekomm beim Auslesen als Datetime eben die Meldung 0.0 ist kein gültiger Zeitstempel.
Wenn ich das Feld auf DateTime setze geht es.

Was für Werte erwartet denn so ein Date-Feld? :cyclops:

Wir haben wegen dieser problem immer nur datetime felder in der BDE benutzt.

Angel4585 2. Aug 2011 19:28

AW: 0.0 ist kein gültiger Zeitstempel
 
Ja genau Paradox, ich werds auch auf Datetime umstellen aber interessieren würds mich schon.

FredlFesl 3. Aug 2011 04:59

AW: 0.0 ist kein gültiger Zeitstempel
 
Ich hab bisher immer Probleme mit 'Date' gehabt, egal mit welcher DB ich gearbeitet habe. Inzwischen denke ich gar nicht mehr daran, 'Date' zu verwenden.

Inzwischen fühlt sich mein Haar viel kräftiger an.

Luckie 3. Aug 2011 06:25

AW: 0.0 ist kein gültiger Zeitstempel
 
Na ja, unter Delphi ist ein DateTime Wert ein Fließkommawert. Der ganzzahlige Anteil repräsentiert den Tag und der Nachkommaanteil den Bruchteil eines Tages, also die Zeit. Da der Datentyp Date keine Zeitangabe besitzt, wird er, vermute ich mal, nicht durch eine Fließkommazahl repräsentiert, sondern durch einen Integer. Und damit wäre eine Fließkommazahl kein gültiger Date Wert.

Angel4585 3. Aug 2011 06:38

AW: 0.0 ist kein gültiger Zeitstempel
 
Verstehe. Und beschreiben klappt weil am Anfang 0 drinsteht was auch als DateTime interpretiert werden kann.
Dann schreibt man ne Fliesskommazahl rein die die Bits weis Gott wie belegt.
Diese Anordnung von Bits wird ab dann beim Auslesen als Integer interpretiert und ergibt so ein Datum.

Luckie 3. Aug 2011 06:42

AW: 0.0 ist kein gültiger Zeitstempel
 
Das ist meine Vermutung.

Daniel 3. Aug 2011 06:46

AW: 0.0 ist kein gültiger Zeitstempel
 
Es kann auch mit dem SQL-Dialekt zusammenhängen. SQL-Dialekt #1 hat ausschließlich DATE-Felder unterstützt, die - ungeachtet ihres Namens - sehr wohl Datum und Uhrzeit aufnehmen konnten. Mit SQL-Dialekt #3 hat sich das geändert, neben DATE kamen die Typen TIME und TIMESTAMP hinzu. Mit der Folge, dass DATE tatsächlich nur noch das Tagesdatum gespeichert hat.

Nun ist SQL-Dialekt #1 aus heutiger Sicht reichlich veraltet, aber es existieren "da draußen" noch genug Datenbanken, die mit diesem alten Dialekt erstellt wurden und nur das ist maßgeblich. Dieser Zustand lässt sich nicht einfach durch das Setzen eine Flags umschalten.

BoolString 3. Aug 2011 10:55

AW: 0.0 ist kein gültiger Zeitstempel
 
Zitat:

Dann schreibt man ne Fliesskommazahl rein die die Bits weis Gott wie belegt.
IEEE754 ;-)

Grüße

Jan



Bei gesteigertem Interesse: Goldberg (1991): What every computer scientist should know about Floating-Point Arithmetic

ASM 10. Aug 2011 23:31

AW: 0.0 ist kein gültiger Zeitstempel
 
Zitat:

Zitat von Luckie (Beitrag 1114834)
Da der Datentyp Date keine Zeitangabe besitzt, wird er, vermute ich mal, nicht durch eine Fließkommazahl repräsentiert, sondern durch einen Integer. Und damit wäre eine Fließkommazahl kein gültiger Date Wert.


Das Thema ist nicht mehr ganz taufrisch, bedarf aber doch deutlicher Korrektur:

Zunächst einiges Grundsätzliche:
Zwar wird der Wert für Date() tatsächlich intern (innerhalb der Funktion TryEncodeDate()) aus der Summe ausschließlich reiner Integerwerte berechnet, er wird aber dennoch eindeutig als Typ TDateTime abgelegt und ist somit de facto vom Typ Double.

So zeigt auch der Code
Code:
showmessage(format('Ausgabewert Date() belegt %d Bytes',[sizeof(date())]));
an, dass der von Date() zurückgegebene Wert tatsächlich 8 Bytes belegt (zur Erinnerung: Integervariablen belegen 4 Bytes)

Von den 8 Bytes einer TDateTime-Variablen werden 4 Bytes für den exponentiellen Anteil, also die Tageszeit verwendet und 4 Bytes für die Mantisse, also das aktuelle Tagedatum, gemäß dem detaillierten Format des Zeitstempels:
Bit Inhalt
-------------------
00-04 Sekunde
05-10 Minute
11-15 Stunde
16-20 Tag
21-24 Monat
25-31 Jahr

Bei Date() werden die Nachkommastellen, welche in TDateTime die Tageszeit definieren, grundsätzlich immer mit 0 belegt.
Dagegen werden bei Time() die Vorkommastellen grundsätzlich immer mit der Bytefolge belegt, die dem Datum 30.12.1899 entspricht, also auf das Datum bezogen ist, welches Delphi seit Delphi 2 als Referenzwert seiner TDateTimezählung verwendet (dies aus Gründen der Kompatibilität zu der zuvor von MS eingeführten OLE 2.0 Automation).

Dementsprechend wirft der Code
Code:
showmessage(format('Date() = %d',[date()]));
die EConvertError-Exception "Format '%d' ungültig oder nicht kompatibel mit Argument",
wogegen der Code
Code:
showmessage(format('Date() = %f',[date()]));
ganz normal ausgibt (am 10.08.2011): "Date() = 40765,00"


Das von Angel4585 beschriebene Problem entsteht nun vielmehr durch einen Bug in der Funktionskette StrToDate() -> TryStrToDate() -> ScanDate() -> ScanNumber(): In ScanNumber() wird die Stringlänge der eingebenen Jahreszahl auf maximal 4 Zeichen gekürzt, sodass eben von der tatsächlich eingegebenen Jahreszahl 11572 nur die gekürzte Jahreszahl 1157 übrigbleibt. Diese aber liegt unterhalb der Referenzjahreszahl 1899 (Wert = 0), wodurch die in TryEncodeDate(Y, M, D, Date) berechnete Date-Variable negativ wird und dadurch letztendlich die beschriebene EConvertError-Exception ausgelöst wird.

Von diesem Problem sind alle Funktionen betroffen, die einen Datumstring in eine TDateTime- bzw. TDate-Variable konvertieren (wie StrToDateTime() und StrToDate()): diese sind also nur für Jahreszahlen bis 9999 einsetzbar!

Interessanterweise ist dem gegenüber als maximaler TDate-Wert 2146790053 erlaubt, was dem Datum 11.Juli 46907 (!) entspricht. Die Konversion eines solch hohen TDate-Wertes in eine Stringvariable ist also von dem o.g. Problem nicht betroffen (obwohl auch hierbei der eigentliche Maxint von 2147483647 nicht erreicht werden kann, allerdings dann keine Exception ausgelöst wird, sondern das Datum oberhalb eines TDate von 2146790053 nur rigoros und ohne Warnung auf 00.00.0000 gesetzt wird).

Luckie 11. Aug 2011 00:27

AW: 0.0 ist kein gültiger Zeitstempel
 
Danke, wieder was gelernt.

Angel4585 11. Aug 2011 07:19

AW: 0.0 ist kein gültiger Zeitstempel
 
Ganz schön lange Erklärung, danke :thumb:
Aber eine Frage:
Zitat:

Zitat von ASM (Beitrag 1116128)
Das von Angel4585 beschriebene Problem entsteht nun vielmehr durch einen Bug in der Funktionskette StrToDate() -> TryStrToDate() -> ScanDate() -> ScanNumber(): In ScanNumber() wird die Stringlänge der eingebenen Jahreszahl auf maximal 4 Zeichen gekürzt, sodass eben von der tatsächlich eingegebenen Jahreszahl 11572 nur die gekürzte Jahreszahl 1157 übrigbleibt. Diese aber liegt unterhalb der Referenzjahreszahl 1899 (Wert = 0), wodurch die in TryEncodeDate(Y, M, D, Date) berechnete Date-Variable negativ wird und dadurch letztendlich die beschriebene EConvertError-Exception ausgelöst wird.

Von diesem Problem sind alle Funktionen betroffen, die einen Datumstring in eine TDateTime- bzw. TDate-Variable konvertieren (wie StrToDateTime() und StrToDate()): diese sind also nur für Jahreszahlen bis 9999 einsetzbar!

Interessanterweise ist dem gegenüber als maximaler TDate-Wert 2146790053 erlaubt, was dem Datum 11.Juli 46907 (!) entspricht. Die Konversion eines solch hohen TDate-Wertes in eine Stringvariable ist also von dem o.g. Problem nicht betroffen (obwohl auch hierbei der eigentliche Maxint von 2147483647 nicht erreicht werden kann, allerdings dann keine Exception ausgelöst wird, sondern das Datum oberhalb eines TDate von 2146790053 nur rigoros und ohne Warnung auf 00.00.0000 gesetzt wird).

Ich geb die 11572 ja nirgends ein. Es wird über .AsDateTime, Now() eingegeben. Also als Jahr 2011. Dann wird da doch nix abgeschnitten.
Oder hab ich jetzt was falsch verstanden? :gruebel:

ASM 11. Aug 2011 09:46

AW: 0.0 ist kein gültiger Zeitstempel
 
Nach den Fakten aus Deiner Beschreibung kann die Deklaration des Feldes in Deiner Tabelle kein numerischer Typ TDate sein, sondern das Feld muss als Typ String vorliegen. Denn wie käme sonst im Feld Deiner Tabelle explizit der Eintrag im Format "dd.mm.yyyy" zustande ? Schließlich ist dieses Format mit einer rein numerischen TDate-, d.h. Double-Variablen, so definitiv nicht möglich, sondern nur als String.

Also wird Deine Eingabe des Datums als Now() zwar zunächst als TDate-Wert angenommen und kann - wie von mir oben beschrieben - intern zur Aufnahme in das Feld dann auch richtig in einen Datumstring umgesetzt werden, selbst wenn die Jahreszahl im String größer als 4 Zeichen werden sollte, wie hier geschehen. Warum jedoch dieser überhöhte Mantissenwert, der zu der Jahreszahl mit mehr als 4 Zeichen führt, bei Dir auftritt, ist aus Deiner alleinigen Angabe, dass Du das Feld über ".AsDateTime auf Now" setzt, nicht nachzuvollziehen. Dazu müsste man die näheren Details zum Code kennen.

Jedenfalls erklärt sich beim anschließenden Wiederauslesen des (String-)Feldeintrages als TDate-Wert die von Dir beobachtete Fehlermeldung exakt aus meiner obigen Erklärung. Denn zwangsläufig muss ja für diesen Vorgang im Hintergrund eine der String->TDateTime-Konversionsroutinen werkeln und somit der Bug aktiv werden.

.

Angel4585 11. Aug 2011 10:49

AW: 0.0 ist kein gültiger Zeitstempel
 
Ahhh verstanden :thumb: Naja da steht im dbd32(Datenbank Explorer) nur Date als Feldtyp ob das dann als String oder Zahl gespeichert wird weis ich natürlich nicht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:01 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