Bernd: Stunden zählen

Hallo,

warum rechnet PHP nicht richtig?


$Arbeitsbeginn = $beginn //07:00;
$Arbeitsende	 = $_POST["ende"] //14:30;
$ABAE = $Arbeitsende - $Arbeitsbeginn //7;

Warum kommen hier nur 7 Stunden raus und nicht 7,5 Stunden?

Auch wenn ich die Werte händisch vergebe, stimmt das Ergebnis leider nicht

$m1 = "07:00";
$m2 = "14:30";
echo $m2 - $m1 //7;

akzeptierte Antworten

  1. Tach!

    warum rechnet PHP nicht richtig?

    PHP rechnet richtig.

    
    $Arbeitsbeginn = $beginn //07:00;
    $Arbeitsende	 = $_POST["ende"] //14:30;
    $ABAE = $Arbeitsende - $Arbeitsbeginn //7;
    

    Warum kommen hier nur 7 Stunden raus und nicht 7,5 Stunden?

    Das ist keine Zeitangabe, sondern das sind Strings. PHP hat Regeln, nach denen String im numerischen Kontext nach Zahlen konvertiert werden. Ein Teil davon ist, dass vom Stringanfang eine Zahl zu erkennen versucht wird, die am ersten Nicht-Zahl-Zeichen endet, in dem Fall am Doppelpunkt. Um mit Zeiten zu rechnen, musst du erstmal den String in ein DateTime-Objekt einlesen, das (und seine Verwandten) hat dann auch Möglichkeiten zum Rechnen.

    dedlfix.

    1. Hallo,

      danke für deine Erklärung. Hab es so jetzt umgesetzt

      $m1 = "07:00";
      $m2 = "14:30";
      
      $start = strtotime($m1);
      $ende  = strtotime($m2);
      $dauerStunden = ($ende - $start)/60;
      		 
      echo $dauerStunden/60;
      

      Als Ergebnis erhalte ich 7,5, was richtig ist.

      1. Hallo Bernd,

        das Ergebnis ist richtig, der Weg hat aber Detailfehler.

        Das einfachste Problem: strtotime liefert Sekunden. Die teilst Du durch 60 und bekommst damit Minuten, die Variable nennst Du aber dauerStunden. Das ist arglistige Täuschung desjenigen, der den Code später liest. Also du.

        Das größere Problem: strtotime liefert den Unix-Timestamp, d.h. Sekunden seit 1.1.1970. Wenn Du ihm einen String ohne Datum übergibst, macht er das mit dem Tagesdatum.

        Solange Du nur tagsüber unterwegs bist, ist das kein Problem. Aber musst Du auch berücksichtigen, dass jemand um 22:00 mit der Arbeit beginnt und um 06:00 Uhr Feierabend macht? Wenn nicht, kannst Du aufhören zu lesen.

        Wenn doch: dann reicht es nicht, strtotime nur mit der Uhrzeit aufzurufen, das Datum muss dazu.

        $m1 = "22:00";
        $m2 = "06:00";
        
        $start = strtotime($m1)/3600;
        $ende  = strtotime($m2)/3600;
        $dauerStunden = ($ende - $start);
        
        echo "Start: $start; Ende: $ende, Dauer: $dauerStunden\n";
        // Start: 428781; Ende: 428765, Dauer: -16
        

        Ups!

        $m1 = "27.11.2018 22:00";
        $m2 = "28.11.2018 06:00";
        
        $start = strtotime($m1)/3600;
        $ende  = strtotime($m2)/3600;
        $dauerStunden = ($ende - $start);
        
        echo "Start: $start; Ende: $ende, Dauer: $dauerStunden\n";
        // Start: 428709; Ende: 428717, Dauer: 8
        

        Besser. Aber wenn wir das gleiche einen Monat früher machen:

        $m1 = "27.10.2018 22:00";
        $m2 = "28.10.2018 06:00";
        
        $start = strtotime($m1)/3600;
        $ende  = strtotime($m2)/3600;
        $dauerStunden = ($ende - $start);
        
        echo "Start: $start; Ende: $ende, Dauer: $dauerStunden\n";
        // Start: 427973; Ende: 427981, Dauer: 8
        

        dann sieht das prima aus, aber leider wird da jemand über eine fehlende Stunde in der Abrechnung motzen. Diese Nacht war eine Stunde länger! Das Ergebnis ist bei mir falsch, weil ich das mit der Sandbox von phponlinefunctions gemacht habe (die die Sommerzeitregeln der USA verwendet). Dein Server ist hoffentlich korrekt auf Mitteleuropa eingestellt, ich hole das für das Beispiel manuell nach:

        date_default_timezone_set ( "Europe/Berlin" );
        $m1 = "27.10.2018 22:00";
        $m2 = "28.10.2018 06:00";
        
        $start = strtotime($m1)/3600;
        $ende  = strtotime($m2)/3600;
        $dauerStunden = ($ende - $start);
        
        echo "Start: $start; Ende: $ende, Dauer: $dauerStunden\n";
        // Start: 427964; Ende: 427973, Dauer: 9
        

        Rolf

        --
        sumpsi - posui - clusi