ugrás a tartalomhoz

idő számítása

tanar · 2005. Jan. 13. (Cs), 15.10
Sziasztok!

Ez vagy nagyon lamer kérdés lesz, vagy tényleg nehezen megoldható, mert én nem jöttem rá a dologra.
Tehát van két változóm, ami időt tárol. Hogy tudom a kettőt kivonni egymásból, hogy idő érték maradjon a végén? És összeadni?
pl:
$q="14:20:00";
$w="16:30:00";

$d=$w-$q;
Tehát az kellene, hogy $d="2:10:00"; -t adjon nekem.
Hogy kell ezt?

Thx.
Tanar
 
1

idő műveletek

Poetro · 2005. Jan. 13. (Cs), 16.14
Legelőször is érdemes megnézni a String-ből időpillanat függvényeket:
strtotime
Másik ami kelleni fog, ami visszaalakítja időpillanatből a neked kellő formátumra: date
Aztán meg jöhet a kivonás.
vhogy így nézne ki a dolog:

<?php
$q="14:20:00";
$w="16:30:00";
$qt=strtotime($q);
$wt=strtotime($w);
$dt=$wt-$qt+82800; //hozzáadunk 23 órát, hogy az óra korrekciója a date-nek jó legyen
$d=date('H:i:s', $dt);
?>
--------
Poetro
2

majdnem jó ez, de...

ftl · 2005. Jan. 13. (Cs), 21.47
ezzel a megoldással azért érhetnek meglepetések a téli/nyári időszámításra történő átállás napján.

$q="01:00:00";
$w="03:00:00";

$qt=strtotime($q, mktime(0,0,0,3,27,2005));
$wt=strtotime($w, mktime(0,0,0,3,27,2005));
$dt=$wt-$qt+82800;
print(date('H:i:s', $dt)."\n");

$qt=strtotime($q, mktime(0,0,0,10,30,2005));
$wt=strtotime($w, mktime(0,0,0,10,30,2005));
$dt=$wt-$qt+82800;
print(date('H:i:s', $dt)."\n");

$qt=strtotime($q);
$wt=strtotime($w);
$dt=$wt-$qt+82800;
print(date('H:i:s', $dt)."\n");


az eredmény:

01:00:00
03:00:00
02:00:00


éjjel 1 és 3 óra között a nyári időszámítás kezdetén csak 1 óra telik el (01:59:59 után 03:00:00 jön), a végén pedig 3 (01:59:59 után 01:00:00 jön).

ebben az átállás dologban van még egy másik csavar is, ugyanis nem mindenütt éjjel 2-kor állítják át az órát, ráadásul nem is ugyanazon a napon... (a legtöbb helyen március utolsó, illetve április első vasárnapján állítják előre, október utolsó vasárnapján pedig vissza.)
(lásd: http://www.timeanddate.com/time/dst2005a.html, http://www.timeanddate.com/time/dst2005b.html)

szóval én javasolnék annyi változtatást, hogy az strtotime() függvényeknek adj valami második paramétert is, mondjuk akár 0-át, hogy ne az aktuális naptól függjön az eredmény. (már ha a dátumtól függetlennek kell lennie...)


alternatív megoldás:

$q="14:20:00";
$w="16:30:00";

function difftime($a, $b) {

list($ah, $am, $as) = explode(":", $a, 3);
list($bh, $bm, $bs) = explode(":", $b, 3);

$ds = $as - $bs;
if ($ds < 0) {
$ds = 60 + $ds;
$remainder = -1;
} else if ($ds > 59) {
$ds = $ds - 60;
$remainder = 1;
}

$dm = $am - $bm + $remainder;
if ($dm < 0) {
$dm = 60 + $dm;
$remainder = -1;
} else if ($dm > 59) {
$dm = $dm - 60;
$remainder = 1;
}

$dh = $ah - $bh + $remainder;

return str_pad($dh, 2, "0", STR_PAD_LEFT).":".str_pad($dm, 2, "0", STR_PAD_LEFT).":".str_pad($ds, 2, "0", STR_PAD_LEFT);
}

print(difftime($w, $q));

(remélem nem csesztem el sehol...)
3

*printf()

bbalint · 2005. Jan. 14. (P), 00.16
a sok str_pad()olás elég "hülyén" néz ki... egy 1*ű sprintf() [talán] olvashatóbb meg minden más:
return(sprintf('%02d:%02d:%02d', $dh, $dm, $ds));

bbalint
4

őőő...

ftl · 2005. Jan. 14. (P), 11.00
hát igen... néha kicsit hülyén fogalmazok. :)
5

téli nyári időszámítás átállás

Poetro · 2005. Jan. 14. (P), 12.39
Nem tudom, hogy az én megoldásomat hol érinti az időátlállás, elvégre minden idő az én megoldásomban 1970. jan. 1-én értendő, és ekkor nem, volt téli nyári időátállás. Főleg mivel itt csak órákról van szó, azaz 24 óra bekorlátozza ezt az intervallumot.
Mondjuk annyi hibát azért érzek az én megoldásomban, hogy nem kezeli le ha maga az időkülönbség negatív, de erre azért írok egy megoldást:

<?php
$q="14:20:00";  // kivonandó dátum
$w="16:30:00";  // amiből ki kell vonni
// időpillannattá konvertálás
$qt=strtotime($q);
$wt=strtotime($w);
// elvégezzük a kivonást és hozzáadunk 23 órát,
// hogy az óra korrekciója a date-nek jó legyen
$dt=$wt-$qt+82800; 
//előjel vizsgálat
$pre='';
if ($dt<0) { // ha az időpillanat negatív
   $dt=-$dt; // időt pozitívvá tesszük, hogy a date fv. jól működjön
   $pre='-'; // előjel ekkor negatív
}
// visszakonvertálás óó:pp:mm formára, és előjelet hozzárakva
$d=$pre.date('H:i:s', $dt);
?>
--------
Poetro
6

az nem 1970 lesz

ftl · 2005. Jan. 14. (P), 15.54
az a baj, hogy a date("Y.m.d. H:i:s", strtotime("14:20:00")) nem 1970.01.01. 14:20:00-at ad vissza, hanem a mai napot (2005.01.14. 14:20:00). (legalábbis azzal a két php-val, amivel eddig próbáltam (5.0.3, 4.3.10).)
a kézikönyvben le is van ez írva:
"A függvény egy stringet vár, amiben egy angolul írt dátum van, és megpróbálja UNIX időbélyeggé konvertálni, a now paramétert, vagy ha az nincs megadva, az aktuális időpontot figyelembe véve."

ha teheted, próbáld meg átállítani a szervered óráját pl. október 30-ra, és nézd meg a 03:00:00 - 01:00:00 eredményét (03:00:00)! (ugyanezt szimulálja a példámban, hogy az strtotime()-nak adok now paramétert, mintha itt lenne a napja az átállásnak...)
7

Nem jó egyik sem, mert csak

tanar · 2005. Jan. 18. (K), 15.08
Nem jó egyik sem, mert csak a kivonás működik, összeadás nem. Nem hiszem el, hogy nem tudja a php az időt rendesen kezelni. Még a nyomorult excel is le tudja kezelni.
Valaki valami mást?
8

Idő

Anonymous · 2005. Jan. 18. (K), 22.28
Az alap problémára visszatérve.

Olyan nincs, hogy van két csak órát és percet tartalmazó változóm. Vagy a mai nap 00:00:00 óta eltelt időt vagy egy másik pl. 1970-hez képest eltelt időt adják meg. Tehát igenis ki lehet vonni vagy összeadni pl. unix időformátumban.

Akinek ez magas az inkább használja azt az "ingyenes excelt", de csak halkan jegyzem meg, hogy ez a fajta dátum kezelés már a PERL-ben (4db fgv. összesen) és a C ben is így volt.
9

deszar a php, mi?

ftl · 2005. Jan. 19. (Sze), 00.58
(a kérdésedben mintha nem lett volna szó összeadásról...)

összedobtam gyorsan egy másik függvényt, ami két [-]hh:mm:ss formátumban átadott időt összead. ha ez sem segít rajtad, akkor tényleg maradj az excel-nél.

$q = "16:30:00";
$w = "-14:20:00";

function sum_hms($a, $b) {

  foreach (array($a, $b) as $t) {
    if (!preg_match('/^[-+]?\d\d:\d\d:\d\d$/', $t)) return false;
    list($th, $tm, $ts) = explode(":", substr($t, -8), 3);
    $tt[] = (($t{0} === '-') ? -1 : 1) * ($th * 3600 + $tm * 60 + $ts);
  }

  $dt = abs($tt[0] + $tt[1]);
  $sig = ($tt[0] + $tt[1]) >= 0 ? "" : "-";

  $dh = floor($dt / 3600);
  $dm = floor(($dt - $dh * 3600) / 60);
  $ds = $dt - $dh * 3600 - $dm * 60;

  return sprintf("$sig%02d:%02d:%02d", $dh, $dm, $ds);
}

print(sum_hms($w, $q));

remélem ezt nem rontom el (bár idétlen megoldások biztos vannak benne - túl fáradt vagyok a gondolkodáshoz). sajnos az előzőbe csúszott hiba, a $remainder változó inicializálatlansága sajnos okozhat gondot... elnézést.

visszatérve a unix timestamp dologra.
én csak arra szerettem volna kilyukadni, hogy aki könnyelműen bánik, vagy nincs tisztában az időzónákkal és a téli-nyári időszámítással, az könnyen úgy járhat, mint például ennek a php "bug"-nak a bejelentője... nem is az összeadással és a kivonással van gond, az oda-vissza konvertálásnál érdemes észnél lenni. pont.