PHP Arbeitszeit mit PHP + MySQL

derkk

Cadet 3rd Year
Registriert
Mai 2009
Beiträge
34
Hallo zusammen,

ich stehe vor folgendem Problem, ich möchte mit PHP in Verbindung mit einer MySQL Datenbank die Arbeitszeit und den dazu entsprechenden Stundenlohn berechnen.

Datenbank Zeit:
id (int)
datum (date)
beginn (time)
ende (time)

Die reine Arbeitszeit kann ich nun in einem SQL-Statement mittels der Funktion TIMEDIFF() berechnen.

1. Annahme:
Stundenlohn: 10,00 €
Arbeitszeit: 03:00:00
Arbeitszeit * Stundenlohn = 30 €

2. Annahme
Stundenlohn: 10,00 €
Arbeitszeit: 03:30:00
Arbeitszeit * Stundenlohn = 30 €

Irgendwas läuft hier nun falsch, kann mir jemand von euch einen Tipp geben wie ich dieses Problem lösen kann. Ich bin für jeden Hinweis / Tipp sehr dankbar.


Viele Grüße
derkk
 
Wenn du die Arbeitszeit als Timevariable speicherst, kannst du diese nicht einfach mit einem Integer/Float multiplizieren, du müsstest die Zeit auch als Integer/Float behandeln, also am besten für 3 Stunden --> 3 und für 3:30 Stunden --> 3,5 Stunden.
 
Wandle die Zeit doch einfach in Sekunden um (TIME_TO_SEC), damit kannst du einfacher rechnen.
 
Passt hier zwar nicht komplett hin, würde deine Datenbank aber etwas verkleinern und längere Zeiten erlauben.

Ich speichere mir mittlerweile immer den Unix Timestamp in der Datenbank ab. Mit dem kannst du schön rechnen.
In deiner DB könntest du damit auch die Datums spalte ersetzen, da das Datum sowieso in deinen Zeiten mit eingebaut ist. Des weiteren entledigst du dich auch einer zusätzlichen Fehlerquelle, sofern du mal Zeiten von plus 24h bekommst.

gruß
 
mit unix_timestamp kan man schlechter rechner,
versuch mal ein monat oder ein jahr drauf zu addieren
und es gibt noch weitere bsp.
 
Vielen Dank für die vielen Antworten.

Kurzfristig hab ich mich für die Lösung mittels der TIME_TO_SEC() Funktion entschieden. Auf lange Sicht werde ich wahrscheinlich doch auf Timestamps umsteigen, da Nachtschichten etc. sonst nicht richtig erfasst werden können.


Viele Grüße
derkk
 
@AlbertLast
Das ist doch prinzipiell auch nur ne ansichtssache. Da muss man dann halt genug sekunden drauf addieren. Auf irgendeinen Wert muss man das ganze doch sowieso runterbrechen. Man kann Datumsberechnungen ja eigentlich auch nicht so einfach trivialisieren. Es sei denn man geht von einem Jahr mit 360Tagen aus. Dann ist es wieder einfacher. So muss man doch auch wieder unterscheiden wie viele Tage der Monat hat, den man dazu addiert. Somit ist es doch prinzipiell egal, wie tief man das ganze runterbricht.

Hier finde ich die Timestamps aber eigentlich recht passend, da hier ja mehr oder minder eine Stechuhr realisiert wird und man direkt einen Start und Endzeitpunkt hat. Ich finde das ganze so persönlich angenehmer zu handhaben, auch wenn es in der Datenbank nicht mehr human readable ist.

Ich würde mich aber über ein paar Beispiele freuen, wo ich mit dem Timestamp auf die Nase fliegen würde. Somit lernich was und trete dann hoffentlich nicht in das Fettnäpfchen.

Was mir gerade aber wieder einfällt. In Java habe ich auch liber mit Time in Millis gearbeitet als mit Calendar :D
 
In Datenbankbereich gibt es Timestamp(Datum, Uhrzeit, Millisekunden und Zeitzone) und unix timestamp (int).

unix timestamp ist limitiert vom anfangs datum (1970) ist kleinste Datum und max 2038.
Daher nicht für Geburtstage geeignet.

unix timestamp kennt keine Zeit zonen, das mysql in timestamp zeitzonen nicht implentiert hat ist persönliches Pech. Richtige rdbms haben das richtig gemacht.

Mit Datum Typen sind interval Rechnung möglich, daher kann man bei ein datum feld + interval 1 month. dann wird aus dem 1.1.2011 -> 1.2.2011

Java hat kein richtiges Datum impentierung, Joda Time ist hier das Mittel der Wahl. Ist auch in Java 8 Standard drin. In PHP 5.4 ist glaube ich auch interval Rechnung drin.

Es gibt zu viel Situationen wo unix timestamp nicht funktioniert, daher würde ich gänzlich weg lassen.
 
Warum machst du nicht einfach Begin/Ende als DATETIME? Die MySQL Datetime werte kannst auch zu unix-timestamp umwandeln (was in deinem fall kein problem wäre), und in der DB ist's sauber lesbar abgelegt. Die Differenz berechnen ist dann auch kein Problem.
 
AlbertLast schrieb:
Es gibt zu viel Situationen wo unix timestamp nicht funktioniert, daher würde ich gänzlich weg lassen.
Das Geburtstagsbeispiel ist das einzige was nicht funktioniert. Plus einen Monat kannst du auch auf Unix Timestamps rechnen.
PHP:
<?php

function pd( $x, $t ) { echo $x.': '.$t.' = '.date( 'd.m.Y H:i:s', $t ).'<br>'; }
function aft( $t, $s, $min = 0, $h = 0, $day = 0, $month = 0, $year = 0 )
{
  return mktime(
    date( 'G', $t ) + $h,
    date( 'i', $t ) + $min,
    date( 's', $t ) + $s,
    date( 'n', $t ) + $month,
    date( 'j', $t ) + $day,
    date( 'Y', $t ) + $year
  );
}

$now = time(); pd( 'now', $now );
$plus_one_year = aft( $now, 0, 0, 0, 0, 0, 1 ); pd( '+1 year', $plus_one_year );
$plus_one_month = aft( $now, 0, 0, 0, 0, 1 ); pd( '+1 month', $plus_one_month );
$plus_one_day = aft( $now, 0, 0, 0, 1 ); pd( '+1 day', $plus_one_day );
$plus_one_hour = aft( $now, 0, 0, 1 ); pd( '+1 hour', $plus_one_hour );
$plus_one_min = aft( $now, 0, 1 ); pd( '+1 minute', $plus_one_min );
$plus_one_sec = aft( $now, 1 ); pd( '+1 second', $plus_one_sec );

?>
Code:
now:       1322575002 = 29.11.2011 14:56:42
+1 year:   1354197402 = 29.11.2012 14:56:42
+1 month:  1325167002 = 29.12.2011 14:56:42
+1 day:    1322661402 = 30.11.2011 14:56:42
+1 hour:   1322578602 = 29.11.2011 15:56:42
+1 minute: 1322575062 = 29.11.2011 14:57:42
+1 second: 1322575003 = 29.11.2011 14:56:43
 
schon klar yuuri,
ich hab mir dein php code nicht ins detail angeschaut,
aber ich vermisste schon mal die Zeitzonen Information.

des Weiteren musste du bei die auch in date wandeln,
wo sich die Frage dann stellt wieso nicht gleich?

Und geht deine Methode nicht mit reinen sql,
die von mir vorgestellt mit interval ginge sogar auf sql ebene.

Zu den Datenfelder würde ich auch sagen solltest anpassen,
begin sollte ein Datetime/timestamp sein, kein unix_timestamp
ende sollte eine time angabe bleiben aber die die dauer angibt.
Damit gibt es weniger probleme bei nachschichten usw.
 
Zuletzt bearbeitet:
Die Zeitzone kann man einfach mittels date_timezone_set setzen.

Und natürlich muss man es bei diesen Funktionen zurückwandeln, es gibt aber auch eine DateTime Klasse, wo du Funktionen wie add() und sub() hast und nicht rückwandeln musst.

Dabei kommt es aber wohl auf den persönlichen Stil an. Ich mag eine Datenbank um Sachen zu speichern und nicht auf Operationen dieser zurückgreifen zu müssen. Wenn ich die Daten atomar speicher und die Logik dem Programm überlasse, hab ich doch eine Abhängigkeit weniger. Weiterhin ist es so einfacher, Dinge interoperabel zu gestalten und kann so bspw. auch Daten in andere Dateien überführen und diese ganz einfach in andere Programme/Programmiersprachen übertragen.
 
die zeitzone information fehlt aber deinem unix timestamp in der db

auch ist denke ich die performance viel besser wenn man schon auf db solche operationen macht, weil sie die daten näher hat und damit auch die datenmenge reduzieren.

und es ist weniger code von nöten diese art von berechnungen zu machen
 
Ist "kommt drauf an" hier nicht die passendere Antwort.
Leider kenne ich mich damit garnicht aus, ob die Berechnungen auf der DB schneller wären. Geht man davon aus, dass man es mit unterschiedlichen Maschinen zu tun hat, wäre es doch bestimmt besser so viel wie möglich auf der DB Maschine zu tun, da man hier ja wirklich direkten Zugriff auf die Daten hat und somit nichts übertragen muss und im anschluss wohl bandbreite spart. Die Maschine muss dann aber auch entsprechend ausgelegt sein, wenn viele Zugriffe stattfinden.
In der normalen Konfiguration, bei der alles auf der gleichen Maschine stattfindet dürfte es wohl nicht so viel Auswirkung haben.

Ob jetzt aber ein direktes Datum oder eine Timestamp verwendet wird hängt ja wirklcih extrem von den Vorlieben und der ARt, wie die Anwendung genutzt wird ab. Man müsste sich auch mal anschauen wie groß der Größenunterschied zwischen einem Date und einem Timestamp ist. Im Normalfall hat man ja genug speicher vorhanden, aber unter manchen Anwendungen wäre dies vielleciht sogar noch von Vorteil.

Naja wengistens hab ich mal wieder was gelernt und freue mcih gerade darüber, dass ich nur mit countdown zeiten arbeiten muss ^^
 
Zurück
Oben