[PHP] Tijd aftrekken

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo,

Ik ben bezig met een website waarop je je uren bij kunt houden.

Je zet er een begintijd in wat opgeslagen wordt als DATETIME. Bijv.
start_date(DATETIME): 2012-06-27 08:00:00
end_date(DATETIME): 2012-06-27 17:00:00

PHP:
1
2
3
<?php 
        $total = ((strtotime($end_date) - strtotime($start_date)) / 3600)
?>

Nu is dit wel van elkaar af te trekken met strtotime alleen ik heb ook nog pauzes.

break_time(TIME): 00:15:00

En hier gaat het altijd fout. Ik heb samen met iemand anders dit script gemaakt:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
            $pauze      = $rij['sessie_pauzetijd'];
            $eindtijd   = $rij['sessie_stopdatum']; 
            $begintijd  = $rij['sessie_startdatum'];
            
            
            $pauzeExplode = explode(':', $pauze);
            
            $uur = intval((strtotime($eindtijd) - strtotime($begintijd)) / 3600) - $pauzeExplode[0];
            $min = intval((strtotime($eindtijd) - strtotime($begintijd)) % 3600 )/ 60 - $pauzeExplode[1];
            
            
            echo '<br />Totaal: '.$uur.':'.$min;

?>

Wat als uitkomst geeft: 9:-15. Is niet een veel simpelere manier wat wel werkt?

Ik licht mijn vraag graag toe.

Mvg,
Mathijs

[ Voor 0% gewijzigd door Creepy op 03-07-2012 15:44 . Reden: Code tags toegevoegd ]


Acties:
  • 0 Henk 'm!

  • Paul
  • Registratie: September 2000
  • Nu online
Bereken het aantal minuten (seconden/uren/jaar/whatever) dat er tussen begin en eind zit, bereken het aantal $eenheid dat je pauze hebt, trek die van elkaar af en ga dan de data die je hebt mooi weergeven zodat jij ook snapt wat er staat :)

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


Acties:
  • 0 Henk 'm!

  • Gamebuster
  • Registratie: Juli 2007
  • Laatst online: 01-08 10:05
http://php.net/manual/en/class.datetime.php en http://php.net/manual/en/class.dateinterval.php
of
http://nl.php.net/manual/en/function.strtotime.php

zijn vrij nuttige onderdelen voor berekeningen met tijd.

[ Voor 16% gewijzigd door Gamebuster op 03-07-2012 09:48 ]

Let op: Mijn post bevat meningen, aannames of onwaarheden


Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Als je het verschil tussen de pauzetijd en 00:00:00 uitrekend, dan kun je hem ook gewoon door strtotime() gooien.

PHP:
1
2
3
4
5
6
7
8
9
date_default_timezone_set('Europe/Amsterdam');

$beginTijd = strtotime('2012-07-03 09:00:00');
$pauzeTijd = strtotime('00:15:00') - strtotime('00:00:00');
$eindTijd = strtotime('2012-07-03 17:00:00');

$werkTijd = $eindTijd - $pauzeTijd - $beginTijd;

echo 'Gewerkte tijd: '. date('H:i:s', $werkTijd); //Gewerkte tijd: 08:45:00

[ Voor 11% gewijzigd door HuHu op 03-07-2012 10:22 . Reden: Foutje in pauzetijd ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dat heb ik ook geprobeerd maar het klopt dan nog steeds niet.

Gewerkte tijd: 09:04:32 is de uitkomt maar dat moet 08:45:00 zijn :(

Acties:
  • 0 Henk 'm!

  • Erkel
  • Registratie: Mei 2006
  • Laatst online: 03-09 10:18
Ik weet dat dit niet de bedoeling is maar goed:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
//Tijden
$breakTime = 15;
$starttime = new DateTime('2012-07-02 08:00');
$endtime = new DateTime('2012-07-02 17:00');

//Verschil tussen tijden berekenen.
$interval = $starttime->diff($endtime);

//Aantal seconden berekenen (verschil in uren * sec per uur)
$seconds = $interval->format('%h') * 3600;

//Gewerkte seconden berekenen
$workedSeconds = $seconds - $breakTime * 60;

//En terug naar uren...
echo $workedSeconds / 3600;
?>


Het had ook korter gekund, maar het is zo wat makkelijker te volgen voor de ts, die volgens mij niet helemaal verstand van zaken heeft. Ik weet dat hier 8.75 uit komt, maar de rest is voor de ts...

[ Voor 4% gewijzigd door Erkel op 03-07-2012 11:02 ]

C2D E6600 - 2048MB Kingston - Sapphire HD2900XT - 200Gb Samsung - Asus P5B-E


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 10-09 18:14

alienfruit

the alien you never expected

Of je gebruikt gewoon https://www.toggl.com :D

Acties:
  • 0 Henk 'm!

  • Kajel
  • Registratie: Oktober 2004
  • Laatst online: 29-07 12:04

Kajel

Development in Style

Inderdaad, de hele propositie klinkt enorm als Not Invented Here(tm) :)

Acties:
  • 0 Henk 'm!

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 11-09 13:16
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
<?php
//Tijden
$breakTime = new DateInterval('PT15M');
$startTime = new DateTime('2012-07-02 08:00');
$endTime = new DateTime('2012-07-02 17:00');

//Verschil tussen tijden berekenen.
$interval = $startTime->diff($endTime->sub($breakTime));

echo $interval->format('%H:%I');

?>


Het had ook simpeler gekund. ;)

Ik snap niet dat PHP geen methods heeft toegevoegd om DateIntervallen van elkaar af te trekken. Dan zou het er zo uit kunnen zien:
PHP:
1
2
$interval = $startTime->diff($endTime);
$interval = $interval->sub($breakTime);

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Note:
Qua implementatie geeft Jaap-Jan als enige de juiste oplossing. Iedereen die ff snel zelf met 60 of 3600 of wat dan ook gaat rekenen gaat keihard op zn gezichtje met bepaalde edge cases met het rekenen met datums/tijden.

{signature}


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Voutloos schreef op dinsdag 03 juli 2012 @ 23:37:
Note:
Qua implementatie geeft Jaap-Jan als enige de juiste oplossing. Iedereen die ff snel zelf met 60 of 3600 of wat dan ook gaat rekenen gaat keihard op zn gezichtje met bepaalde edge cases met het rekenen met datums/tijden.
^ Wat hij en hij zegt

http://infiniteundo.com/p...ammers-believe-about-time
http://infiniteundo.com/p...believe-about-time-wisdom

Laat daarom 't rekenen met datum/tijd als 't effe kan over aan beschikbare native functies of bekende libraries (zoals bijv. Joda/Noda Time) (even aangenomen dat die fatsoenlijk geïmplementeerd zijn :P ).

Having said that; als je met die edge-cases die (misschien) fout gaan kunt leven: deze post ter kennisgeving aannemen en onthouden voor een volgende keer :P

Nog beter is enkel een starttijd opslaan en een "duratie" per item (in minuten, secondes, <insert_gewenste_resolutie>) op te slaan. Dan heb je heel dat gezeik allemaal niet met die edge-cases (althans, niet in 't rekenen; totaal = x.duratie + y.duratie + z.duratie) niet. Enkel in je presentatielaag (waar je een eindtijd wil tonen) zul je diezelfde voorgenoemde tip(s) moeten gebruiken om de correcte datum/tijd-waarde te tonen.

[ Voor 20% gewijzigd door RobIII op 04-07-2012 00:31 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Voutloos schreef op dinsdag 03 juli 2012 @ 23:37:
Note:
Qua implementatie geeft Jaap-Jan als enige de juiste oplossing. Iedereen die ff snel zelf met 60 of 3600 of wat dan ook gaat rekenen gaat keihard op zn gezichtje met bepaalde edge cases met het rekenen met datums/tijden.
Ook die van Jaap-Jan is helaas niet juist:

PHP:
1
2
3
4
5
6
7
8
$breakTime = new DateInterval('PT15M'); 
$startTime = new DateTime('2012-03-25 00:00'); 
$endTime = new DateTime('2012-03-25 08:00');

//Verschil tussen tijden berekenen. 
$interval = $startTime->diff($endTime->sub($breakTime)); 

echo $interval->format('%H:%I'); // 07:45 


Op 25 maart 2012 gaat de zomertijd in, waarbij de klok van 2 naar 3 uur wordt gezet. Er zitten dan dus 7 werkuren tussen 00:00 en 08:00, met een kwartier pauze maakt dat 06:45 werkuren en niet 07:45.

Dit geldt overigens voor alle code hierboven, ook die van mijzelf.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Ja klopt, maar ja, dan moet je maar niet de timezone parameter achterwege laten. :P

{signature}


Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Voutloos schreef op woensdag 04 juli 2012 @ 10:21:
Ja klopt, maar ja, dan moet je maar niet de timezone parameter achterwege laten. :P
Dat maakt niet uit. Ik deed standaard een date_default_timezone_set('Europe/Amsterdam');, maar ook het expliciet toevoegen van de timezone parameter in de constructor van DateTime helpt niet.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hoewel je vaak kunt vertrouwen op libraries, gaat dat bij datum libraries over het algemeen dan vaak weer niet op 8)7

Het enige wat een DateInterval doet is de verschillen opslaan in de notatiewijze van een datumtijd. Het representeert niet een vaste tijdsperiode! Als je dat wel wilt, dan moet je gewoon met timestamps gaan rekenen. Ondanks wat sommige mensen beweren is de code van Jaap-Jan dus niet correct.

[ Voor 61% gewijzigd door .oisyn op 04-07-2012 12:47 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 09-09 14:07
Is het niet gewoon het beste/makkelijkste, zoals oisyn als zegt, om gewoon om te rekenen naar een timestamp? Zo zou ik het gewoon doen?

Ik wil eigenlijk helemaal geen datums weten, ik wil tijdsverschillen weten. Weliswaar tussen 2 data, maar dat terzijde.

Kortom: wat is er mis met omrekenen naar timestamps en die allemaal van elkaar aftrekken?

Dit is een serieuze vraag, want het is zo voor de hand liggend en toch roept eigenlijk niemand het.... Denk ik ook verkeerd?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Kortom: wat is er mis met omrekenen naar timestamps en die allemaal van elkaar aftrekken?
Niets :). Waar je voor moet oppassen is dat je niet secondes gaat gebruiken om een periode als "1 dag" of "1 maand" weer te geven, want die zijn natuurlijk tijds- en tijdzoneafhankelijk

[ Voor 45% gewijzigd door .oisyn op 05-07-2012 12:45 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Massiefje schreef op donderdag 05 juli 2012 @ 12:25:
Ik wil eigenlijk helemaal geen datums weten, ik wil tijdsverschillen weten. Weliswaar tussen 2 data, maar dat terzijde.
Je wil, volgens mij, geen tijdsverschillen weten maar duraties ;) En dan heb je 2 dingen nodig: starttijd en duratie. Hoe je die duratie opslaat (seconden, minuten, vierkante koeien per speciekuip) is dan alleen relevant voor de "resolutie" die je wil hebben. Dat is hoe ik 't zou doen, maar goed, wie ben ik :P

[ Voor 11% gewijzigd door RobIII op 05-07-2012 13:12 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Corniel
  • Registratie: April 2002
  • Laatst online: 31-03 14:56

Corniel

De wereld is gek!

Als je niet - zoals geopperd - een bestaand pakket neemt (wat waarschijnlijk het beste advies moet je volgens mij het volgende doen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class WorkingTimeSpan
{
    // Choose the prefered precision.
    var workingTimeInMinutes = 0;

    public WorkingTimeSpan($ticks) {
        $this->workingTimeInMinutes = intval($ticks);
    }

    public function toString() {
        return $this->getTotalHours().':'.$this->getMinutes();
    }

    public function getTotalMinutes() {
         return intval($this->workingTimeInMinutes);
    }
    public function getTotalHours() {
         return intval($this->workingTimeInMinutes/60);
    }
    public function getMinutes() {
         return intval($this->workingTimeInMinutes%60);
    }

    public static function fromDates($start, $end) {
         $ticks = 123;// todo implement.
         var span = new WorkingTimeSpan($ticks);
         return $ticks;
    }
    public static function fromSomethingElse($input) {
         $ticks = 123;// todo implement.
         var span = new WorkingTimeSpan($ticks);
         return $ticks;
    }
}


Kortom: schrijf een klein domeinobject, dat je logica bevat. en sla het op in de voor JOUW probleem nuttige eenheid. Minuten zouden zomaar de beste kunnen zijn. (tenzij jullie mensen uitbetalen per seconde?!)

[ Voor 8% gewijzigd door Corniel op 05-07-2012 13:15 . Reden: te vroeg verstuurd. ]

while (me.Alive) {
me.KickAss();
}


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

RobIII schreef op donderdag 05 juli 2012 @ 13:11:
[...]

Je wil, volgens mij, geen tijdsverschillen weten maar duraties ;)
Je kan wel zelf termen gaan verzinnen maar 't is toch echt hetzelfde hoor ;). Het gaat hier voornamelijk om de eenheid van een verschil / interval / duratie - tijdvaste of tijdsafhankelijke eenheden. Welke je wilt hangt af van de situatie (als je iets hebt dat iedere dag moet gebeuren dan wil je juist weer een tijdsafhankelijke eenheid - een DateInterval in PHP)
En dan heb je 2 dingen nodig: starttijd en duratie. Hoe je die duratie opslaat (seconden, minuten, vierkante koeien per speciekuip) is dan alleen relevant voor de "resolutie" die je wil hebben. Dat is hoe ik 't zou doen, maar goed, wie ben ik :P
Dan verplaats je het probleem alleen maar. In je presentatielaag wil je namelijk een eindtijd kiezen, dus zul je dáár de duratie moeten uitrekenen. Met alle blijkelijke problemen van dien.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Massiefje
  • Registratie: Mei 2002
  • Laatst online: 09-09 14:07
.oisyn schreef op donderdag 05 juli 2012 @ 12:43:
[...]

Niets :). Waar je voor moet oppassen is dat je niet secondes gaat gebruiken om een periode als "1 dag" of "1 maand" weer te geven, want die zijn natuurlijk tijds- en tijdzoneafhankelijk
Tnx. Goed om te lezen dat ik het begrepen heb :P
Pagina: 1