Udregning af antal timer

Tags:    php mysql

Hejsa.

Hvis jeg ønsker at kunne udregne antal timer jeg har været på arbejde ud fra indtastede arbejdstid.

Fx at jeg arbejder fra 9 - 19.15 som jo er 10,25 timer og så kan jeg blot gange min timeløn på.

Hvordan kan jeg løse denne problemstilling nemmest?

Der skal også senere kobles på hvis jeg får tillæg i et givent tidsrum

fx at fra 18-19 får jeg 25,- ekstra.

Er på helt bar bund.

Håber der er en der kan hjælpe mig lidt videre.




33 svar postet i denne tråd vises herunder
4 indlæg har modtaget i alt 12 karma
Sorter efter stemmer Sorter efter dato
Løsningen som Jens beskriver ovenfor er fin nok - men alt for kompliceret.

MySQL (som også er tagget på denne tråd) indeholder allerede en masse gode funktioner til at arbejde med tid og tidsforskelle. (REF: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html )


En simpel MySQL tabel skulle kunne klare arbejdet - noget i stil med: id (int, primkey), fra (timestamp), til (timestamp)

Derefter laver du alle dine udregninger med SQL i queries - der er ikke nogen grund til at lave beregninger i PHP.

Funktionen som vi er særligt interesserede i er TIME_DIFF; Den tager to argumenter, altså fra og til, og returnerer forskellen i tid. http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_timediff

SELECT SEC_TO_TIME(SUM(TO_SECONDS(TIME_DIFF(fra,til)))) FROM arbejdstid WHERE fra >= '2012-01-01 00:00:00' AND til <= '2012-01-31 23:59:00'

Ovenstående query returnerer tid du har arbejdet mellem 1 januar 2012 og 31 januar 2012, i formatet: TT:MM: SS (edit: mellemrummet er for at undgå tossede smileys!)

Du kan tilføje WHERE clauses som filtrere på projekter osv efter ønske.

Det er meget nemmere at bruge de indbyggede funktioner i relationelle databaser end at genopfinde dem i scripting sprog. Datetime datatypen i MySQL er endda meget fleksibel, og det er muligt at sekund konverteringen i min SELECT parameter i ovenstående query ikke engang er nødvendig - men det kan du nærlæse i manualen jeg linkede til.

PHPs rolle i dette tilfælde er at lave et interface til databasen, så du kan vælge hvilke data du vil se - hvilken måned (eller andet interval), hvilken projekt - og det kan gøre håndteringen af input til databasen nemmere. Men at håndtere beregningen i PHP er ikke effektivt eller nemt. Det er den allerede lange tråd et godt eksempel på ;-)

edit: Glemte at tage højde for tillæg; Det nemmeste er at køre to queries i stil med ovenstående; den første tager alle sekunder mellem fra og til i hele perioden, den anden tager sekunder mellem 18:00 og 23:59:59 i fra og til intervaller i hele perioden. Derefter er anslået løn blot ligmed: resultat1-resultat2 * basisløn/sekund + resultat2*basisløn/sekund. Simple nestede select statements er alt der er brug for: SELECT r.resultat1, r.resultat2 FROM ((SELECT resultat1 FROM ...) UNION (SELECT resultat2 FROM ...)) AS r




Indlæg senest redigeret d. 27.01.2012 15:39 af Bruger #17015
eh... :)

Hvis:
60 min = 1

så er det givet at:
9:00 = 9 og 19:15 = 19.25

tid = 19.25 - 9 = 10.25


Tillæg kan så udregnes ved

(19.25 - 18) * 25

En lang formel kan lyde

f(x) = (b - a) * x + sqr((b - 18) * (b - 18)) * y

a = start tid,
b = slut tid
x = timeløn
y = tillæg

Frokost regnes normalt for en halv time og der er normalt indlagt to ekstra pauser, kl 9.30 og kl. 14 af hhv. 10min og 15min.



Indlæg senest redigeret d. 26.01.2012 10:43 af Bruger #10216
Kør den her query i dit SQL interface (PHPMyAdmin, SQLBuddy, whatever):

Fold kodeboks ind/udSQL kode 


Formatet for output er Timer : Minutter : Sekunder. Mit output ses nedenfor:

Fold kodeboks ind/udKode 




Indlæg senest redigeret d. 29.01.2012 20:00 af Bruger #17015
Fejlen du får siger at linje 24 mysql_fetch_assoc ikke får et sql resultat men en boolean. mysql_query returnerer enten resultatet af din query eller en boolsk false værdi hvis det ikke kan køre din query.

Så der er en fejl i din query. Fjern linebreaks (\n) og fjern escaping af single quotes. Så;

Fold kodeboks ind/udPHP kode 




Daniel, er det noget du skal programmere eller er det bare en udregning til dig selv?




Hvis:
60 min = 1

så er det givet at:
9:00 = 9 og 19.15 = 19.25


Du angiver 60 min. = 1 og så skriver du tiden i deci-timer neden under?


Frokost regnes normalt for en halv time og der er normalt indlagt to ekstra pauser, kl 9.30 og kl. 14 af hhv. 10min og 15min.


Ahhh, det er vist en meget generel betragtning du kommer med der ;-) Det kommer helt an på sted, overenskomst, osv.



Indlæg senest redigeret d. 25.01.2012 22:00 af Bruger #9814
Har lige rettet en tegnfejl. :)

og du har ret mht. frokost og pauser, at det er generelt betragtning. Men jeg må dog antage at enhver arbejdsplads som minimum overholder denne betragtning, da det ellers er tvivlsomt at arbejdspladsen vil kunne holde på sine medarbejdere.

Tænk hvis du var ryger, og du kun havde frokostpausen... :)



rimelig sikker på det her er forkert:
f(x) = (b - a) * x + sqr((b - 18) * (b - 18)) * y

Hvis han arbejdede mindre end kl 18 ville han få tillæg for de timer mindre han arbejdede.

funktion t tager tiden givet som et tids decimal tal (efter komma kun 0-60) og konvertere det til et decimal tal.
t(a) = floor(a) + (a % 1) * 1.66666667;

f(x, y, a, b) = (t(b) - t(a)) * x + max(t(b) - 18, 0) * y

Dog siger du kun tillæg mellem 18-19, så burde det her være mere rigtigt:
f(x, y, a, b) = (t(b) - t(a)) * x + min(max(t(b) - 18, 0), 1) * y





Forkert og forkert... det er blot antaget at der altid arbejdes til over kl. 18. ;)

Det må være et spørgsmål om morale. :)



Ja jeg overvejede at kommentere den antagelse, men hvis du virkelig foretog den antagelse, så:
sqr((b - 18) * (b - 18)) === (b - 18)

Det du gør er jo reelt:

sqr(x^2)




Jeg synes at det er nemmere at arbejde med unix timestamps og sekunder.
Så beregner man antallet af sekunder mellem to tidspunkter og så kan man gøre med dem, hvad man vil...omregne til antal timer ved at dividere med antal sekunder på en time.
De fleste funktioner arbejder med sekunder, så det vil være det mest naturlige...synes jeg :-)

Ved at bruge timestamps løser du også problemet med at hvis du arbejder fra kl. 22 til kl. 02, så har du ikke arbejdet i minus 20 timer.



t