Raik: Berechnung ist fehlerhaft

Hallo!

ich versuche, aus einer exportierten (*.csv) buchungsübersicht meines bankingprogrammes die datumsfelder in einen timestamp umzuwandeln und diesen durch 86400 (entspricht 24 std) zu teilen, um auf den tageweisen abstand der einzelnen buchungen voneinander zu kommen.
(das ganze soll dann per gdlib zu einem diagram verarbeitet werden.)
bei einigen datumswerten ergeben sich dabei aber immer wieder nachkommastellen, die ich mir nicht erklären kann. (z.b. beim 27.10.2003)

"20.10.2003";"-721,39"
"20.10.2003";"-732,88"
"22.10.2003";"-782,88"
"23.10.2003";"-1032,88"
"24.10.2003";"-1051,19"
"27.10.2003";"-1037,10"
"27.10.2003";"-1095,80"
"27.10.2003";"-1097,33"
"28.10.2003";"-1083,24"
"30.10.2003";"-1015,23"
"30.10.2003";"-1095,23"
....

  
<?php  
$csv = file ("Export.csv");  
$alldata = array();  
$month = array("01"=>"Jan","02"=>"Feb","03"=>"Mar","04"=>"Apr","05"=>"May","06"=>"Jun",  
   "07"=>"Jul","08"=>"Aug","09"=>"Sep","10"=>"Oct","11"=>"Nov","12"=>"Dec");  
foreach ($csv as $set){  
$set = str_replace('"', '', $set);  
$data = explode(';', $set);  
$date = str_replace(".".substr($data[0], 3, 2).".", " ".$month[substr($data[0], 3, 2)]." ", $data[0]);  
$data[0] =  strtotime($date) / 86400;  
$alldata[] = $data;  
}  
print_r ($alldata);  
?>  

ist das ein fehler von php, oder von mir?

freundl. Grüsse aus Berlin, Raik

  1. Hallo,

    ist das ein fehler von php, oder von mir?

    Ich sehr zwar keinen Fehler, aber egal.

    Also das ist weder ein Fehler von dir, noch von PHP.
    Das liegt mit der Speicherung von Float-Zahlen zusammen.

    Bsp:
    <?php
    for($i=0.01;$i!=1;$i+=0.01)
    ?>

    Theoretisch würde diese Schleife ja beendet werden, irgendwann ist 1 erreicht => Schleife bricht ab.
    Aber praktisch erhält man so oft eine Endlosschleife.
    Denn der PC kann, wie gesagt, dezimal/float Zahlen nicht richtig speichern.

    So wäre folgendes möglich:
    0.98
    0.99999999999
    1.00000000001

    Dabei sind die letzten beiden Zahlen unmöglich.

    Deswegen musst du bei genauen Zahlen, mit Strings rechnen.
    So wird die Zahl nicht als float, sondern als String gespeichert, und dann damit gerechnet.
    In PHP gibt es für solche Berechnungen die Bibliothek: BC

    <?php
    //Ungetestet
    for($i="0.01";$i!="1";$i=bcadd($i,"0.01"))
    ?>

    Die Funktionen erkennst du an dem bc vor den Namen ;)

    MFG
    Andavos

  2. echo $begrüßung;

    bei einigen datumswerten ergeben sich dabei aber immer wieder nachkommastellen, die ich mir nicht erklären kann. (z.b. beim 27.10.2003)

    Schau doch mal bitte im Kalender nach, was da für ein Zusatz zu diesem Tag (bzw. zum davorliegenden Sonntage) vermerkt ist. Ende März hast du sicherlich das gleiche Problem? Und das jedes Jahr?

    echo "$verabschiedung $name";

    1. Hallo, dedlfix!

      Schau doch mal bitte im Kalender nach, was da für ein Zusatz zu diesem Tag (bzw. zum davorliegenden Sonntage) vermerkt ist. Ende März hast du sicherlich das gleiche Problem? Und das jedes Jahr?

      du hast recht, da spielt mir die sommerzeit nen streich.
      nun könnte ich den "fehler" durch die eine stunde einfach abrunden, aber gibts nicht auch eine elegantere möglichkeit, das zu korrigieren?
      ich hab mich bei den datums- und zeitfunktionen schon mal umgesehen, aber noch nichts brauchbares gefunden.

      freundl. Grüsse aus Berlin, Raik

      1. Hello,

        du hast recht, da spielt mir die sommerzeit nen streich.
        nun könnte ich den "fehler" durch die eine stunde einfach abrunden, aber gibts nicht auch eine elegantere möglichkeit, das zu korrigieren?

        strtotime() ?

        Harzliche Grüße vom Berg
        esst mehr http://www.harte-harzer.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau
      2. echo $begrüßung;

        du hast recht, da spielt mir die sommerzeit nen streich.

        Der Sommerzeitfehler spielt aber in dem von dir geposteten Teil noch keine Rolle. Da kommt es jedoch zu den von Andavos beschriebenen Fehlern bei der Darstellung von Fließkommazahlen, da in $data[0] nach der Division des Timestamps durch 86400 ein float-Wert landet. Hier funkt auch noch die Zeitzone dazwischen. Ohne Angabe derselben in deinem Stringwert geht strtotime() von der lokal auf dem Rechner eingestellten aus. Und da bekommst du dann (hierzulande und bei korrekter Zeitzoneneinstellung) 1 oder 2 Stunden Vorsprung und krumme Werte beim Dividieren mit ganzen Tagen.
        Füge deinem Datumsstring noch ein ' UTC' hinzu und du hast erstmal dieses Problem gelöst. Die Division durch 86400 ergibt dann auch Integer-Werte.

        ich hab mich bei den datums- und zeitfunktionen schon mal umgesehen, aber noch nichts brauchbares gefunden.

        Alle gm*-Funktionen rechnen mit GMT(UTC), also durch Zeitzonen und Sommerzeit unbeeinflusst.

        echo "$verabschiedung $name";

        1. Hallo, dedlfix!

          Füge deinem Datumsstring noch ein ' UTC' hinzu und du hast erstmal dieses Problem gelöst. Die Division durch 86400 ergibt dann auch Integer-Werte.

          vielen dank, jetzt funktionierts! :-)

          freundl. Grüsse aus Berlin, Raik