[PHP] Laptimes berekenen

Pagina: 1
Acties:
  • 322 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • siepeltjuh
  • Registratie: Maart 2003
  • Niet online
Via search kwam ik op 600+ threads, maar die doet het net andersom.
Het geval is namelijk dat ik van een string bijvoorbeeld: '1:41.123' terug naar het aantal seconden wil gaan.

Dit kan ik oplossen door een explode of splitdan de x minuten *60 etc, maar dat vind ik zelf niet zo`n mooie oplossing. Het zou toch gewoon zo moeten zijn dat je dit eenvoudig in 1 regel terug moet krijgen naar seconden.

Van seconden naar een dergelijke string krijg ik wel voor elkaar met date en mktime. maar deze weg werkt volgens mij maar in 1 richting.

Waarbij seconden dan 3 decimalen heeft. Op PHP.net heb ik al eindeloos zitten zoeken, maar zijn alleen datum dingen te vinden.

Can`t live without the mods


Acties:
  • 0 Henk 'm!

  • Aloys
  • Registratie: Juni 2005
  • Niet online

Acties:
  • 0 Henk 'm!

  • Bitage
  • Registratie: April 2006
  • Laatst online: 19-05-2024
Dus jij doet
code:
1
2
3
4
5
$time = explode(":","1:41.123");

$time = ( $time[0] * 60 ) + $time[1];

// Zal '101.123' teruggeven


Als dat voor je doet wat je wilt, waarom is dat dan niet netjes genoeg voor je?

[ Voor 7% gewijzigd door Bitage op 26-10-2007 21:30 ]


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Wil je dit overzichtelijk implementeren, kom je sowieso niet om een eigen functie heen. Wanneer je daarin explode zou doen, hoeft dat niet gelijk een onoverzichtelijke applicatie op te leveren.

@hierboven: strtotime lijkt me trouwens niet zo geschikt, omdat unix timestamps hier niet van belang zijn en die bovendien niet nauwkeuriger zijn dan tot op de seconde.

Acties:
  • 0 Henk 'm!

  • siepeltjuh
  • Registratie: Maart 2003
  • Niet online
Inderdaad het overzicht bewaren is een belangrijk punt. een functie helpt dan.

Stom zeg dat ik daar niet aan heb gedacht. Moet misschien maar even stoppen, ben de hele dag al bezig, en zie nu dit soort simepele dingen niet meer.

$buffer = explode(':', $oude_tijd);

$nieuwe_tijd = ($buffer[0]*60)+$buffer[1];

Dat had ik er zelf al van gemaakt. Je hebt gelijk als het doet wat het moet doen is het goed. Maar er komen van allerlij plekken verschillende soorten data, die allemaal in de db geplempt moeten worden. Omdat alles aangeleverde data rommel is, en overal string bewerking op toegepast moet wordne wordt het snel een overzichtelijke puinhoop, daarom wil ik alles zo kort mogelijk, efficient mogelijk en overizchtelijk mogelijk.

Uit jullie reacties begijp ik dat hier geen standaard functie voor is. (strtotime werkt niet met miliseconden en kan ook niets met deze straing - geeft altijd false terug)
Heb de functie zelf gemaakt, en toegepast, mocht iemand nog een makkelijkere - lees kortere - variant hebben. Dan hou ik me aanbevolen.

Can`t live without the mods


Acties:
  • 0 Henk 'm!

  • ? ?
  • Registratie: Mei 2007
  • Niet online

? ?

http://be.php.net/microtime ?

in je database moet je soieso geen datums als string opslaan, gewoon om te tonen doe je een conversie naar een string

[ Voor 67% gewijzigd door ? ? op 26-10-2007 22:13 ]


Acties:
  • 0 Henk 'm!

  • siepeltjuh
  • Registratie: Maart 2003
  • Niet online
era.zer schreef op vrijdag 26 oktober 2007 @ 22:12:
http://be.php.net/microtime ?

in je database moet je soieso geen datums als string opslaan, gewoon om te tonen doe je een conversie naar een string
No office, maar dan moet je beter lezen. Er word nergens een datum opslagen als int. Dat zou nooit moeten.

Wat ik heb is een stopwatch tijd. die sla je doorgaans wel op als int. Omdat daar dan mee gerekend kan worden als stopwatch tijd in mysql zelf.
Dezelfde reden waarom je een datum opslaat als datum in mysql omdat je er anders niet mee kan rekenen.

Ontopic dus maar weer.

Can`t live without the mods


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 20:01
siepeltjuh schreef op vrijdag 26 oktober 2007 @ 22:32:
[...]


No office, maar dan moet je beter lezen. Er word nergens een datum opslagen als int. Dat zou nooit moeten.
No offence, maar je moet ook beter lezen. :)

Hij zegt niet dat je je datum niet als string moet opslaan, waar hij wel gelijk in heeft; jij spreekt dat je je datum niet als int moet opslaan.
En eigenlijk vind ik dat je daar verkeerd in bent. In het type 'DateTime' wordt de datum ook mbhv 2 integers opgeslagen, eentje voor de datum, en eentje voor de tijd.
Het is dus helemaal geen slecht idee om in jouw geval je ronde-tijden ook als int in de DB op te slaan (in milliseconden bv).
In jouw voorbeeld wordt de ronde-tijd '1:41:123' dan opgeslagen als 60 * 1000 + 41 * 1000 + 123 = 101123.

Het enige wat je dan nog moet doen, is er voor zorgen dat je die ronde tijd in een begrijpbaar / leesbaar formaat presenteert. Dan zal je dus een functie moeten schrijven die die ronde-tijd (in int), omzet naar een string representatie van '1:41:123'.

Dergelijke manier van werken is foutloos, nauwkeurig, en maakt het ook makkelijk om ronde-tijden te gaan vergelijken.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • siepeltjuh
  • Registratie: Maart 2003
  • Niet online
Hmm volgens mij praten we langs elkaar.

Ik sla het op als een decimal 7,3 Dat lijkt me de beste methode.

101.234 staat er dan.

Met de tekst
in je database moet je soieso geen datums als string opslaan
Impliceert hij dat er datums als string worden opgeslagen. Dat doe ik niet, is ook nooit aan de orde geweest. Ik snap niet dat hij over datums begint, er is nooit gesproken over een datum.

In het stukje dat ik had getypt staat int, ik bedoelde string. wat waarschijnlijk voor jou verwarrend is geweest. Lees het nu terug, en bedoelde daar toch echt string. maar goed.

Het wordt opgeslagen naar decimal 7,3 dan hoef ik geen functie meer te schrijven die het e.e.a. omrekent van miliseconden naar volle int. (x1000 dus) (voor string terug naar decimal doe ik met in bovengenoemde post)

Ben geholpen. :) Erg bedankt. Nu moet ik het weer de andere kant op maken, maar dat is niet zo heel ingewikkeld. Toch jammer dat PHP niet rekent met miliseconden en tijd genereren enz. Neem aan dat er ontzettend vaak gebruikt wordt van dergelijke functies voor tijdmetingen/stopwatchtijden zou mooi zijn als daar een standaard functie voor bijgemaakt word om het e.e.a. van string naar int/decimal en weer terug te krijgen.
En nee microtime heeft hier niets mee van doen.

[ Voor 17% gewijzigd door siepeltjuh op 28-10-2007 20:34 ]

Can`t live without the mods


Acties:
  • 0 Henk 'm!

  • siepeltjuh
  • Registratie: Maart 2003
  • Niet online
Bij een 1:05.123 komt een vervelend punt, die wordt echter weergegeven asl 1:5.123. De 0 mist dan tussen 1 en 9 seconden.

Mijn oplossing:
PHP:
1
2
3
4
5
6
function seconds_to_str($seconds)
    {
    $buffer = explode('.', $seconds);
    $seconden = (strlen($buffer[0]%60) == 1) ? '0'.($buffer[0]%60) : ($buffer[0]%60) ;
    return floor($buffer[0]/60).':'.$seconden.'.'.$buffer[1];
    }


Zijn daar nog goede of slechte gedachten over?


Dan kom ik vervolgens bij het berekenen van de onderlinge verschillen:

PHP:
1
2
3
$decimal1 = 70.381;
$decimal2 = 70.180;
echo $str-$int;

Dit is een test voorbeeld en geeft 0.20099999999999 het zou gewoon 0.201 moeten zijn. Waarom reageert PHP zo? Natuurlijk is dit met een round af te vangen, maar het is mijn inziens een bijzonder vreemd gedrag. Overigens gebruik ik PHP 5.2.4

[ Voor 31% gewijzigd door siepeltjuh op 28-10-2007 21:44 ]

Can`t live without the mods


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 22:47
siepeltjuh schreef op zondag 28 oktober 2007 @ 21:16:
Dit is een test voorbeeld en geeft 0.20099999999999 het zou gewoon 0.201 moeten zijn. Waarom reageert PHP zo? Natuurlijk is dit met een round af te vangen, maar het is mijn inziens een bijzonder vreemd gedrag. Overigens gebruik ik PHP 5.2.4
Je gebruikt floats, daarmee komt bepaald gedrag. Dit voorkomen is vrij simpel en al meerdere keren je geadviseerd: gebruik integers. Als jij dan toch eigenwijs wilt zijn prima, maar bedenk dat er een reden is waarom de mensen hier je iets aanraden ;)

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • siepeltjuh
  • Registratie: Maart 2003
  • Niet online
Het is een tijd geleden, maar kwam in mn history dit weer tegen.

Het probleem is opgelost, maar kan dit niet laten ver eeuwigen :)

In de DB worden Decimal 7,3 gebruikt, daarover ging de discussie, dat is de beste oplossing, ints zorgen er voor dat je achteraf weer moet rekenen. De data opslaan in het type zoals het hoort. xxx.xxx is een decimal, dus sla je ook zo op. in MySQL that is.

Maar de laatste vraag ging over PHP zelf. Daar is mij nog nooit geadviseerd ints te gebruiken in dit thread. Weet niet waar je dat vandaan haalt.

Wat ik mij niet realiseerde was dat als ik $tijd = 123.123; als statement neerpoot PHP dit dan automatisch als float gaat gebruiken, ik dacht (omdat ik mysql in mn kop had) dat hij dat zou zien als een decimal met 3 karakters achter de komma. 8)7

Can`t live without the mods


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Dat is niet zo gek, PHP kent helemaal geen decimals.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 20:01
siepeltjuh schreef op dinsdag 13 november 2007 @ 00:59:
Het is een tijd geleden, maar kwam in mn history dit weer tegen.

Het probleem is opgelost, maar kan dit niet laten ver eeuwigen :)

In de DB worden Decimal 7,3 gebruikt, daarover ging de discussie, dat is de beste oplossing, ints zorgen er voor dat je achteraf weer moet rekenen. De data opslaan in het type zoals het hoort. xxx.xxx is een decimal, dus sla je ook zo op. in MySQL that is.
Ik blijf er bij dat decimal in dit geval niet de beste keuze is.
Je laptime bevat helemaal geen cijfers na de komma; je lap-time bestaat uit een aantal seconden (of milliseconden, afhankelijk van hoe nauwkeurig je hem wilt hebben).
Als je die laptime nu in een decimal steekt, dan moet je 'm toch ook gaan omrekenen ?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Daarnaast is rekenen met floating point getallen een hele kunst op zich, je komt al snel in rare afrondingsfouten terecht en dan kan het flink zoeken zijn waar het probleem zit.

Je hebt voor jezelf een doelstelling om iets met een bepaalde precisie op te slaan en kiest daarbij logisch voor milliseconden, dan is er helemaal niets mis met het opslaan als integer om gelijk die precisie vast te leggen. Dat je later moet rekenen is logisch, dat moet vrijwel altijd, het komt maar zelden voor dat je gegevens uit de database 1:1 wilt representeren naar de bezoeker.

Zo zie je dat in veel financiele systemen bedragen ook als integer worden opgeslagen, met een vaste precisie van een cent of een tiende cent.

Waarom floating point getallen evil zijn als het om precisie aankomt staat hier goed beschreven: http://en.wikipedia.org/wiki/Floating_point

Zie het kopje 'Accuracy problems'

[ Voor 11% gewijzigd door Verwijderd op 13-11-2007 09:32 ]


Acties:
  • 0 Henk 'm!

  • siepeltjuh
  • Registratie: Maart 2003
  • Niet online
Dat maakt het wat duidelijker.

Zoals Whoami zegt, ik ging uit van seconden. Ik wil ook het miliseconden weten, dus was er mijn inziens een decimal nodig. Echter PHP kent dat niet. en gebruikt int of float.

SQL kent het wel, daar heb ik dan ook decimal gebruikt, dacht dat ik het kon doorzetten in PHP. was niet zo mijn fout.

Het is nu dan ook opgelost door zowel in PHP als in SQL ints te gebruiken, pas bij het presenteren breng ik het naar een string.

Voor het rekenen maakt het ook niet uit.

Can`t live without the mods


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 22:47
siepeltjuh schreef op dinsdag 13 november 2007 @ 00:59:
Maar de laatste vraag ging over PHP zelf. Daar is mij nog nooit geadviseerd ints te gebruiken in dit thread. Weet niet waar je dat vandaan haalt.
whoami schreef op zaterdag 27 oktober 2007 @ 11:16:
No offence, maar je moet ook beter lezen. :)
[...]
Het is dus helemaal geen slecht idee om in jouw geval je ronde-tijden ook als int in de DB op te slaan (in milliseconden bv).
I rest my case.

Decimals zijn leuk maar in feite niets meer dan ints met een puntlocatie - niet een "echt" datatype op zich, enkel een representatie naar jou toe vanaf je databaseengine. Leuk, maar doorgaans vrij nutteloos. Voor het rekenen maakt het ook wel degelijk uit wat je gebruikt, int berekeningen zijn in PHP een stuk sneller dan string-berekeningen en wel accuraat.

PHP mag dan soft-typed zijn, de types zijn nog steeds wel degelijk aanwezig en het goede type gebruiken voor de juiste situatie maakt je code logischer, sneller en minder foutgevoelig. :)

[ Site ] [ twitch ] [ jijbuis ]

Pagina: 1