Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php]Odejmowanie dwóch godzin
Forum PHP.pl > Forum > Przedszkole
code46
Nie wiem jak poradzić sobie z problemem odejmowania dwóch godzin. Poniżej przykłady i wyniki jakie chciałbym uzyskać.

19.30 - 6.00 -> 13,5
16.45 - 8.00 -> 8,45
16.32 - 7.10 - > 9,22
batman
Pisane z palca, ale powinno działać.
  1. <?php
  2. $h1 = 16;
  3. $h2 = 7;
  4. $m1 = 32;
  5. $m2 = 10;
  6.  
  7. echo date("H:i", mktime(($h1 - $h2), ($m1 - $m2)));
  8. ?>


edit
Przed chwilą poniżej była wypowiedź podważająca działanie tego kodu winksmiley.jpg


Tak, to zadziała, ponieważ, jeśli $h1 < $h2, to obliczy godzinę dla dnia poprzedniego:
  1. <?php
  2. echo date("d H:i", mktime(($h1 - $h2), ($m1 - $m2)));
  3. ?>
Jarod
Potrzebuję sposobu podobnego do tego zaprezentowanego wyżej ale bez konieczności rozbijania godzin na minuty.
Tzn, że z bazy pobieram dwie godziny np:

$a = '16:32';
$b = '07:10';

Chcę uniknąć używania explode() w wiadomych przyczyn. Macie jakiś pomysł? Bo do tej pory robiłem to tak:
  1. <?php
  2. $fResult = date("H.i", strtotime($aWTR['koniec_pracy'])) - date("H.i", strtotime($aWTR['poczatek_pracy']));
  3. ?>


Ale przy godzinach

07:45
16:15

wynik 8,7 a powinno być 8,5 godziny. Musiałbym wyciągnąć wartości setne i tą wartość odjąć od 100. Za dużo danych i to zbyt duże obciążenie.
Kicok
Wywal obie funkcje date (zostaw tylko strtotime) i podziel sobie wynik przez 3600.
Jarod
Cytat(Kicok @ 30.04.2008, 15:30:08 ) *
Wywal obie funkcje date (zostaw tylko strtotime) i podziel sobie wynik przez 3600.


Działa dla godzin:
07:45
16:15

natomiast dla godzin:
$a = '16:32';
$b = '07:10';

podaje wynik 9.36 co jest głupotą.. Powinno być 9,22. Potrzebuje sposobu, który zawsze dobrze obliczy..
lilik
naprosciej wedlug mnie

  1. <?php
  2. $c1 = strtotime("16:32");
  3. $c2 = strtotime("07:10");
  4. $czas1 = $c1-2*3600;
  5. $czas2 = $c2-2*3600;
  6. echo date("H:i", $czas1); 
  7. echo date("H:i", $czas2);
  8. ?>
Jarod
Cytat(lilik @ 30.04.2008, 16:50:02 ) *
naprosciej wedlug mnie

  1. <?php
  2. $c1 = strtotime("16:32");
  3. $c2 = strtotime("07:10");
  4. $czas1 = $c1-2*3600;
  5. $czas2 = $c2-2*3600;
  6. echo date("H:i", $czas1); 
  7. echo date("H:i", $czas2);
  8. ?>



Sprawdzę. Wytłumacz dlaczego
Kod
-2   *3600


EDIT:.
Co chciałeś osiągnąć tym kodem? Spróbuj odjąć od godziny 16:32 godzinę 7:10... Ma ktoś jakiś inny pomysł?
lilik
prosze bardzo

  1. <?php
  2. $c1 = strtotime("16:32");
  3. $c2 = strtotime("07:10");
  4. $czas1 = $c1-$c2;
  5.  
  6. echo date("H:i", $czas1);
  7. ?>


wynik 10:22
Jarod
Cytat(lilik @ 30.04.2008, 17:48:52 ) *
wynik 10:22


Wiem jaki daje wynik bo sprawdzałem. Uważasz, że jest prawidłowy?:/
Kicok
Cytat
Działa dla godzin:
07:45
16:15

natomiast dla godzin:
$a = '16:32';
$b = '07:10';

podaje wynik 9.36 co jest głupotą.. Powinno być 9,22.


Wzorowałem się na twoim drugim poście, w którym napisałeś:
Cytat
Ale przy godzinach

07:45
16:15

wynik - 8,7 a powinno być 8,5 godziny.

Więc jeśli różnica wynosi "dziewięć i pół godziny" to skrypt wyświetli 9,5. Jeśli natomiast różnica wynosi "dziewięć i dwadzieścia dwa sześćdziesiąte godziny", to wyświetli: 9,36

Jeśli zamiast 9,5 chcesz mieć 9:30, to:
Kod
$godziny = floor( $roznica_w_sekundach / 3600 );
$minuty = ( $roznica_w_sekundach % 3600 ) / 60
Jarod
Cytat(Kicok @ 30.04.2008, 18:16:39 ) *
Jeśli zamiast 9,5 chcesz mieć 9:30, to:
Kod
$godziny = floor( $roznica_w_sekundach / 3600 );
$minuty = ( $roznica_w_sekundach % 3600 ) / 60


@Kicok: rozumiem, tylko, musiałbym rozbić godziny i minuty za pomocą explode() co nie jest mi na rękę ze względów wydajnościowych.
Generalnie sprowadziłeś rozwiązanie do rozwiązania batmana.
erix
  1. <?php
  2. $c1 = strtotime("16:32");
  3. $c2 = strtotime("07:10");
  4. if($c1>$c2){
  5. echo date('H:i', $c1-$c2);
  6. }else{
  7. echo date('H:i', $c2-$c1);
  8. }
  9. ?>

?
Jarod
@erix: przecież ten kod zwraca błędy wynik.. 10:22? Powinno być 9:22 winksmiley.jpg
erix
Dorzuć
  1. <?php
  2. date_default_timezone_set('UTC');
  3. ?>

na początku. ;]
Jarod
Mam
  1. <?php
  2. date_default_timezone_set('Europe/Warsaw');
  3. ?>
Dlaczego UTC?
erix
Szczerze mówiąc, sam nie mogę trochę zrozumieć, dlaczego... sciana.gif

Ale przy strefie UTC przelicza prawidłowo, przy innych już dodaje tą nadmiarową godzinę. Niby przesunięcie czasowe powinno być takie same w obu przypadkach...
lilik
oj to wystarczy odjac ta dodatkowa godzine

  1. <?php
  2. $c1 = strtotime("16:32");
  3. $c2 = strtotime("07:10");
  4. $czas1 = ($c1-$c2) -3600;
  5. echo date("H:i", $czas1);
  6. ?>
erix
Ok, zmienią się ustawienia czasu (zimowy/letni) i będzie trzeba kombinować. A podejrzewam, że i to może mieć wpływ...
Kicok
Cytat
@Kicok: rozumiem, tylko, musiałbym rozbić godziny i minuty za pomocą explode() co nie jest mi na rękę ze względów wydajnościowych.
Generalnie sprowadziłeś rozwiązanie do rozwiązania batmana.


Kiedy ja o jakimś explode wspominałem? strtotime" title="Zobacz w manualu PHP" target="_manual
  1. <?php
  2.  
  3. $a = '16:32';
  4. $b = '07:10';
  5.  
  6. $roznica_w_sekundach = strtotime( $a ) - strtotime( $b );
  7.  
  8.  
  9. $godziny = floor( $roznica_w_sekundach / 3600 );
  10. $minuty = ( $roznica_w_sekundach % 3600 ) / 60;
  11.  
  12. echo "$godziny:$minuty";
  13.  
  14. ?>



A po drugie to skąd to przekonanie, że explode jest mało wydajne? Według tego testu jest o wiele wydajniejsze niż używanie strtotime" title="Zobacz w manualu PHP" target="_manual:
  1. <?php
  2.  
  3. date_default_timezone_set( 'Europe/Warsaw' );
  4.  
  5. $a = '16:32';
  6. $b = '07:10';
  7.  
  8.  
  9. // Sposób 1
  10.  
  11. $start1 = microtime( true );
  12. for( $i = 0; $i < 100000; $i++ )
  13. {
  14. $roznica_w_sekundach = strtotime( $a ) - strtotime( $b );
  15.  
  16. $godziny = floor( $roznica_w_sekundach / 3600 );
  17. $minuty = ( $roznica_w_sekundach % 3600 ) / 60;
  18. }
  19. $stop1 = microtime( true );
  20. //
  21. echo "Sposób 1: $godziny:$minuty - " . ( $stop1 - $start1 ) . '<br />';
  22.  
  23. // Sposób 2
  24. $start2 = microtime( true );
  25. for( $i=0; $i < 100000; $i++ )
  26. {
  27. $czasa = explode( ':', $a );
  28. $czasb = explode( ':', $b );
  29.  
  30. $roznica_w_minutach = ( $czasa[0] * 60 + $czasa[1] ) - ( $czasb[0] * 60 + $czasb[1] );
  31.  
  32. $godziny = floor( $roznica_w_minutach / 60 );
  33. $minuty = $roznica_w_minutach % 60;
  34. }
  35. $stop2 = microtime( true );
  36. //
  37. echo "Sposób 2: $godziny:$minuty - " . ( $stop2 - $start2 ) . '<br />';
  38.  
  39. ?>
Jarod
@Kicok: Nie doczytałem dokładnie Twojego wcześniejszego posta. Dzięki za wyjaśnienie. Niestety nie mogę dać pomógł ale widzę że dostałeś plusa.

pzdr.

Jeszcze mam jeden problem. Mam dwie godziny:
17:00 i 01:25 chciałbym odjąć od 17:00 01:25 ale nie mogę zrobić tego w ten sposób:
strtotime("17:00") - strtotime("01:25") ponieważ strtotime przeliczy mi 01:25 na uniksowy znacznik czasu. Potrzebuje 01:25 zamienić na ilość sekund. Nie ilość sekund od epoki unixa.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.