Autor |
Beitrag |
Lake
      
Beiträge: 78
D6 prof., Delphi 10.2 Tokyo
|
Verfasst: Mi 29.05.13 12:57
Hallo ich verstehe etwas nicht.
Wenn ich folgendes Statement (SQL-Server2008) absetze:
(das Feld GueltigVon ist vom Typ DateTime)
SQL-Anweisung 1:
| Select CAST(GueltigVon as Integer) as Zahl, GueltigVon from [Tabelle]; |
Erhalte ich folgendes Ergebnis:
|Zahl | GueltigVon |
+------+------------+
|29219 | 01.01.1980 |
Zur Prüfung des Wertes mache ich folgendes
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| var dDatum : TDateTime; fWert : Double begin ... dDatum := EncodeDate(1980,1,1); fWert := Double(dDatum ))); ... end; |
Der Wert von fWert ist aber 29221 und nicht 29219.
Auch die Prüfung in Excel gibt für den 01.01.1980 29221 aus.
Warum ergeben sich hier Unterschiede und wie läßt sich das vermeiden?
_________________ Gruss Lake
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Mi 29.05.13 13:40
Lass Dir doch einfach mal die 0 als Datum ausgeben, dabei ergibt das dann unter Delphi den 30.12.1899 und unter MSSQL den 01.01.1900. Das macht 2 Tage Unterschied, die Du berücksichtigen musst.
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Mi 29.05.13 19:04
Lake hat folgendes geschrieben : | Der Wert von fWert ist aber 29221 und nicht 29219.
Auch die Prüfung in Excel gibt für den 01.01.1980 29221 aus.
Warum ergeben sich hier Unterschiede und wie läßt sich das vermeiden? |
Die einfachste Lösung wäre sicherlich, kein TDateTime bei Datenbanken zu verwenden. Man kann das Datum und die Uhrzeit auch in einzelnen Feldern speichern. Z. B.:
datJahr = 2013
datMonat = 5
datTag = 29
Oder als String: "20130529"
Bei einer Uhrzeit entsprechend.
Bei den Zeitangaben kocht doch jeder Hersteller sein eigenes Süppchen. Der Wert bei Excel hängt von den Excel-Optionen ab (1901- oder 1904-Format). Siehe hierzu: office.microsoft.com...calculations_and_for
Mein Festplattenreceiver arbeitet intern beim Erstellen der Film-Header sogar mit dem Modifizierten Julianischem Datum (Nullpunkt der Zeitskala = 17. November 1858).
|
|
Mathematiker
      
Beiträge: 2622
Erhaltene Danke: 1448
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Mi 29.05.13 20:11
Hallo,
Gerd Kayser hat folgendes geschrieben : | Mein Festplattenreceiver arbeitet intern beim Erstellen der Film-Header sogar mit dem Modifizierten Julianischem Datum (Nullpunkt der Zeitskala = 17. November 1858). |
und deshalb: Warum arbeitest Du nicht mit Deinen eigenen Datumszahlen. Das Julianische Datum ist wirklich nicht schlecht, da es denn ganzen Ärger mit den Schaltjahren umgeht.
Die Differenz zweier Julianischer Daten gibt stets den wahren Abstand von zwei Tagen an.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| function julianischesdatum(const jahr,mon,tag:integer):integer; var y,m,k:longint; a,b:real; begin k:=10000*jahr+100*mon+tag; b:=-63.5; y:=jahr+4712; m:=mon+1; if mon<=2 then begin dec(y); inc(m,12); end; if k>=15821015 then begin a:=int((y+88)/100); b:=b+38-a+int(0.25*a); end; result:=trunc(int(365.25*y)+int(30.6001*m)+tag+b); result:=round(int(365.25*y)+int(30.6001*m)+tag+b-2400000.5); end; |
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Mi 29.05.13 22:03
Mathematiker hat folgendes geschrieben : | Warum arbeitest Du nicht mit Deinen eigenen Datumszahlen. Das Julianische Datum ist wirklich nicht schlecht, da es denn ganzen Ärger mit den Schaltjahren umgeht.
Die Differenz zweier Julianischer Daten gibt stets den wahren Abstand von zwei Tagen an.
Delphi-Quelltext 1:
| result:=round(int(365.25*y)+int(30.6001*m)+tag+b-2400000.5); | |
Es gibt doch die Funktion
Delphi-Quelltext 1:
| function ModifiedJulianDateToDateTime(const AValue: Double): TDateTime; |
Der Fragesteller stellte eine Abweichung von 2 Tagen fest. Wenn mal die Datenbank auf die einer anderen Firma umgestellt wird, hat er die Differenz vielleicht nicht mehr, sie bleibt gleich oder ändert sich. Da kommt sicherlich Freude auf, wenn dann die Anwendung und ggf. die Daten angepasst werden müssen. Eine Datumsangabe z. B. in der Form 20130529 ist eindeutig, eine fortlaufende Zahl wie beim TDateTime aber nicht. Selbst Delphi hatte damals beim Versionssprung von Delphi 1 nach Delphi 2 (wenn ich mich bei den Versionsnummern jetzt nicht irre) den Bezugszeitpunkt bei TDateTime geändert. Exportiert man die Daten nach Excel, ist es von den Einstellung bei den Optionen abhängig, wie dort die Werte interpretiert werden.
Mit EncodeDate usw. kann man das innerhalb der Anwendung ggf. für die weitere Verarbeitung der Anwendung umrechnen.
Ich sehe jedenfalls überwiegend Vorteile, wenn man das Datum praktisch im Klartext in der Datenbank ablegt.
|
|
Mathematiker
      
Beiträge: 2622
Erhaltene Danke: 1448
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Mi 29.05.13 22:40
Hallo,
Gerd Kayser hat folgendes geschrieben : | Es gibt doch die Funktion
Delphi-Quelltext 1:
| function ModifiedJulianDateToDateTime(const AValue: Double): TDateTime; | |
Bei meinem alten Delphi 5 gibt es das noch nicht.
Es freut mich aber, dass diese Funktion bei moderneren "Delphis" aufgenommen wurde.
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Do 30.05.13 09:48
Man könnte aber auch die komplette Berechnung clientseitig durchführen, da ist dann das Offset unerheblich, und die DB-Struktur muss nicht geändert werden.
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Do 30.05.13 11:01
Nur kurz, ich muss gleich los. Aber bevor hier noch mehr so tolle Ideen kommen wie "Datum als 3 Felder speichern"
Man rechnet nicht mit der internen Darstellung von Datumswerten. Nie. Dafür bietet jede Umgebung entsprechende Wrapper an, die dann auch Schaltjahre, Sommerzeit, Schaltsekunden, UTC/GMT und sonstige Absurditäten beachten. Die Anzahl der Stunden zwischen 2 Zeitpunkten ist zum Beispiel ziemlich oft nicht einfach die Anzahl der Tage mal 24...
Entweder also die Berechnung in der DB machen oder aber als TDateTime-Spalte abholen und dann mit dem Field rechnen, dann wird die Umsetzung vom Binding übernommen (meistens über den Umweg einer String-Repräsentation).
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Do 30.05.13 11:17
Für diesen Beitrag haben gedankt: Martok
|
|
Lake 
      
Beiträge: 78
D6 prof., Delphi 10.2 Tokyo
|
Verfasst: Do 30.05.13 19:53
Vielen Dank für die Posts.
In zukünftigen Projekten werde ich da Datum als String ablegen.
Für die alten Projekte deren Daten nun auf dem SQL-Server liegen werde ich nach einer Möglichkeit suchen dies Problem zu umgehen.
Danke an Alle
_________________ Gruss Lake
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Do 30.05.13 21:40
Lake hat folgendes geschrieben : | In zukünftigen Projekten werde ich da Datum als String ablegen. |
Bei einem Datum als String besteht immer die Gefahr, dass Daten falsch eingegeben werden können. Stichwort wäre z. B. das amerikanische und das deutsche Format (Monat und Tag vertauscht). Dazu noch die Trennzeichen (Punkt, Schrägstrich, Bindestrich). Eine Aufteilung des Datums in year, month, day (jeweils als Zahl abgespeichert) hat Vorteile, auch wenn manche hier das ignorieren wollen. Es kommt immer darauf an, wie die Daten am Günstigsten vorliegen sollen. Beim Löschen eines gesamten Jahres braucht man nur das Jahr anzugeben. Sogar einen Monat eines bestimmten Jahres kann man so gezielt und einfach löschen.
Wenn man mal in Google nach "datenbanken datetime probleme" sucht, wird man von der Masse der Ergebnisse förmlich erschlagen.
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Fr 31.05.13 08:37
Ich erkenne den Sinn, ein Datenformat in ein anderes zu quetschen, irgendwie nicht, obwohl ich so etwas immer wieder sehe 
|
|