Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[PHP] DateTime, aanpassen minuten

Pagina: 1
Acties:

  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Voor een functie wil ik het verschil in uren tussen 2 data uitrekenen in uren en minuten.De user zelf kan datum en tijd kiezen met een dropdown op een formulier en dat voeg ik samen tot een datum:

code:
1
2
3
$datum1 = new DateTime($datum.$van);
            $datum2 = new DateTime($datum.$tot);
            $interval = $datum1->diff($datum2);

Vervolgens wil ik weten hoeveel minuten dit zijn, want als het meer is dan 330 minuten (5.5 uur) moet er een half uur af.
code:
1
$minuten = ($interval->h * 60) + $interval->i;


Vraag is nu, hoe kun je met DateTime opnieuw de interval uitrekenen rekening houdende met die 30 minuten die er af moeten? Zeg maar:
code:
1
2
3
$datum1 = new DateTime($datum.$van);
$datum2 = new DateTime($datum.$tot - 30 minuten);
$interval = $datum1->diff($datum2);


edit:

Als volgt opgelost:

code:
1
2
3
4
$datum1 = new DateTime($datum.$van);
$datum2 = new DateTime($datum.$tot);
$datum2  = $datum2->modify('-30 min');
$interval = $datum1->diff($datum2);

[ Voor 11% gewijzigd door ViNyL op 06-03-2013 15:10 ]


  • Hatsieflatsie
  • Registratie: Oktober 2011
  • Laatst online: 20-11 21:25
PHP n00b hier, dus pin mij niet op vast. Maar zou het volgende evt. handiger zijn:

[code=PHP]
<?php
$datum1 = new DateTime($datum.$van);
$datum2 = new DateTime($datum.$tot);
$minuten = ($interval->h * 60) + $interval->i;
If $minuten(>330)
{
$datum2 = $datum2->modify('-30 min');
$interval = $datum1->diff($datum2);
echo $interval
}
else
{
echo $minuten
}
?>
[/code=PHP]

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22-11 13:46

Janoz

Moderator Devschuur®

!litemod

Waarom zou trouwens een
PHP:
1
2
3
if ($minuten > 330) {
  $minuten = $minuten - 30;
}

niet voldoen?

Maar goed, ik zou je code nog maar eens even heel goed gaan testen voordat je het live gaat zetten.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Janoz schreef op donderdag 07 maart 2013 @ 07:17:
Maar goed, ik zou je code nog maar eens even heel goed gaan testen voordat je het live gaat zetten.
Om een specifieke reden? Dat lijkt me namelijk logisch, maar het werkt precies zoals het moet. Ik reken het alleen om naar minuten om te kijken of het langer dan 5.5 uur is. Dat is makkelijker te checken.
Hatsieflatsie schreef op donderdag 07 maart 2013 @ 00:26:
PHP n00b hier, dus pin mij niet op vast. Maar zou het volgende evt. handiger zijn:

[code=PHP]
<?php
$datum1 = new DateTime($datum.$van);
$datum2 = new DateTime($datum.$tot);
$minuten = ($interval->h * 60) + $interval->i;
If $minuten(>330)
{
$datum2 = $datum2->modify('-30 min');
$interval = $datum1->diff($datum2);
echo $interval
}
else
{
echo $minuten
}
?>
[/code=PHP]
Ik doe het inderdaad op deze manier nu!

[ Voor 40% gewijzigd door ViNyL op 07-03-2013 08:54 ]


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22-11 13:46

Janoz

Moderator Devschuur®

!litemod

ViNyL schreef op donderdag 07 maart 2013 @ 08:50:
Om een specifieke reden? Dat lijkt me namelijk logisch, maar het werkt precies zoals het moet.
Nou, er zijn op dit moment twee mogelijkheden:

1 - Php is brak
2 - Jouw code is brak

Normaal zou eigenlijk altijd van 2 uitgaan, echter bij php heeft de geschiedenis mij geleerd dat ik 1 niet uit kan sluiten.

Maar goed. Bedenk maar eens een aantal testgevallen en kijk of het resultaat wel het gewenste resultaat is.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Ik heb meerdere testgevallen doorlopen en het resultaat is zoals verwacht. Volgens mij is de code die ik gebruikt ook vrijwel volgens de manual, dan zou alleen optie 1 over blijven. Maar goed daarom is testen ook belangrijk.

Voorbeeld uit de manual om interval te berekenen:
code:
1
2
3
4
$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-13');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days');


Voorbeeld van het aanpassen van een datum/tijd:
code:
1
2
3
$date = new DateTime('2006-12-12');
$date->modify('+1 day');
echo $date->format('Y-m-d')

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22-11 13:46

Janoz

Moderator Devschuur®

!litemod

Welke testgevallen had je dan en waarom denk je dat je daarmee alle mogelijke situaties afgedekt hebt?

--
Edit, op phpfiddle.org maar even een testje gedaan en tot de conclusie gekomen dat het in dit geval inderdaad om situatie 2 gaat.

[ Voor 40% gewijzigd door Janoz op 07-03-2013 13:27 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Ik snap niet waar de aanvallende ondertoon vandaan komt. Misschien ligt het aan mij maar constructief werkt niet.

Als ik het volgende aangeef:

code:
1
2
3
$datum1 = new DateTime('07-03-2013 14:00');
$datum2 = new DateTime('07-03-2013 19:31');
$interval = $datum1->diff($datum2);


Krijg ik een object met:
code:
1
DateInterval Object ( [y] => 0 [m] => 0 [d] => 0 [h] => 5 [i] => 31 [s] => 0 [invert] => 0 [days] => 0 )


Doe je vervolgens dit:
code:
1
$minuten = ($interval->h * 60) + $interval->i;


Dan is het aantal minuten 331.
Dat lijkt mij als een bus te kloppen zover.

Als ik er vervolgens dit doet:
code:
1
$datum2   = $datum2->modify('-30 min');


Dan is het resultaat 301 minuten.

Wat klopt daar dan niet aan? En ik hoor graag wat er brak aan is, want dan kan ik daar wat mee doen.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22-11 13:46

Janoz

Moderator Devschuur®

!litemod

Ik kan het wel voorkauwen, maar dan leer je het niet. Ik probeer je zelf te laten nadenken hoe je kan garanderen dat je code ook juist is. Wat ik hierboven zie is slechts 1 testgeval. Als je daarop baseert dat je script ook werkt dan heeft het wel een heel hoog 'it compiles, lets ship it' gehalte. Een werkelijke test bestaat uit meerdere testgevallen waarbij je ook de randvoorwaarden aftest.

Probeer gewoon eens minimaal 3 verschillende situaties te bedenken die je op deze code loslaat.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Ah dat bedoel je.

Gelukkig is het in dit geval al makkelijk omdat het slechts steeds om 1 en dezelfde datum gaat. Het loopt nooit over meerdere dagen. Ook controleer ik eerst of de tot tijd niet in het verleden ligt, de data en tijd wel geldig zijn en niet bv 84 maart 1870.

Ik zal het nog eens goed doorlopen.

  • Pin0
  • Registratie: November 2002
  • Niet online
Zeker met datums zijn er nogal wat randgevallen. Oud- Nieuwjaar, voor 1970, voor 0000, schrikkeljaren, 30-2-2013 etc. Zelf Apple had een datum bug in de iPhone wekker. Datums zijn altijd tricky...

Dus checken is inderdaad geen overbodige luxe...

Mijn Lego Mocs - LEGO idea: The Motorcycle Garage


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22-11 13:46

Janoz

Moderator Devschuur®

!litemod

Je zult altijd moeten checken, niet alleen bij datums. Zeker met wat rand gevallen. De bug die ik in eerste instantie gespot heb, baseerde ik op
verschil in uren tussen 2 data uitrekenen in uren en minuten
maar nu blijkt dat
Gelukkig is het in dit geval al makkelijk omdat het slechts steeds om 1 en dezelfde datum gaat.
Dan zal die bug niet optreden, maar dan vraag ik me af waarom je uberhaupt datums gebruikt. Is het dan niet gewoon veel makkelijker om dropdowns voor uren en minuten te gebruiken? Of moet je rekening hoduen met zomertijd (om nog maar eens een ander randgeval aan te halen)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Ik gebruik dropdowns voor uren en minuten. Daar kan dus weinig mis gaan (los van het aanpassen van de HTML bron, maar ik check de waardes alsnog).

Omdat ik niet dagelijks met data en tijden werk ging ik er in eerste instantie vanuit dat de datum nodig was, dit blijkt niet zo te zijn. Ik gebruik de datum dan ook alleen nog voor het vermelden op het formulier en de e-mails die verstuurd worden.

Misschien wat verwarring, excuse me O+

[ Voor 5% gewijzigd door ViNyL op 07-03-2013 15:13 ]


  • Hatsieflatsie
  • Registratie: Oktober 2011
  • Laatst online: 20-11 21:25
Post eens de volledige script van je functie?

Wellicht dat het nog geoptimaliseerd kan worden.

  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
De velden bij de variablen "van" en "tot" komen van het form en worden met een dropdown gekozen. Eerst worden deze gecheckt (kloppen de tijden, etc) en dan samengesteld:
code:
1
2
$van = $velden[$i]['van-uren'].":".$velden[$i]['van-min'];
$tot  = $velden[$i]['tot-uren'].":".$velden[$i]['tot-min'];


Het volgende wordt vervolgens doorlopen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
$vanTijd           = new DateTime($van);
$totTijd            = new DateTime($tot);
$interval           = $vanTijd ->diff($totTijd);
$aantalMinuten = ($interval->h * 60) + $interval->i;

if ($aantalMinuten > 330)
{            
$vanTijd           = new DateTime($van);
$totTijd            = new DateTime($tot);
$totTijd            = $totTijd->modify('-30 min');
$interval           = $vanTijd->diff($totTijd);
$aantalMinuten = ($interval->h * 60) + $interval->i; 
}

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22-11 13:46

Janoz

Moderator Devschuur®

!litemod

Ik vind het een beetje moeilijkdoenerij om eerlijk te zijn.

PHP:
1
2
3
4
$minuten = 60* ($tot-uren - $van-uren) + ($tot-min - $van-min);
if ($minuten > 330) {
  $minuten = minuten - 30;
}

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Daar heb je misschien wel gelijk in.
Pagina: 1