Ich habe vor kurzem für ein Web-Projekt eine Zeitanzeige gebraucht, wollte aber nicht immer nur ein schnödes Datum anzeigen. Viel lieber eine Darstellung à la “vor soundsoviel Stunden und 3 Minuten ist in China ein Sack Reis umgefallen”. Für den englischsprachigen Raum gibt es da schon viele fertige Codeschnipsel, für deutsche Scripts sicher auch – aber ich wollte mir lieber selber einen Code basteln, von dem ich weiß wie er funktioniert. Hier gibt’s das ganze jetzt Schritt für Schritt. Wer einfach nur die Funktion benutzen will, findet am Ende des Artikels den Downloadlink!
Vorbereitungen
Zuerst einige grundlegende Variablen, die wir definieren müssen. Man soll der Funktion ein bis zwei Timestamps übergeben können, so dass daraus die Differenz berechnet wird. Der erste Parameter $ts ist der Zeitpunkt um den es geht, der zweite Parameter ist optional:
1 | function timesince($ts,$t0=false) |
Wir berechnen gleich die Zeitdifferenz. Wenn kein zweiter Parameter übergeben wurde, wird time(), also die aktuelle Zeit verwendet:
3 4 5 6 | // Referenz-Zeit: Wenn nicht übergeben, dann die aktuelle Zeit. $t = ($t0===false) ? time() : intval($t0); // Zeitdifferenz mit übergebener Zeit $tdiff = $t-$ts; |
Weitere Vorbereitungen: Wir brauchen außerdem verschiedene Arrays, um die verschiedenen Zeiteinheiten zu verwalten. Ein Array für die Einheiten an sich, eines für die Plural-Endungen (falls nötig) und ein Array für die Faktoren, um wieviel eine Zeiteinheit jeweils das Vielfache einer Sekunde ist.
7 8 9 10 11 12 | // Zeit-Einheiten $units = array("Sekunde","Minute","Stunde","Tag","Woche","Monat","Jahr"); // Plural-Suffixe der Zeit-Einheiten $unit_p = array("n","n","n","en","n","en","en"); // Multiplikatoren der Zeit-Einheiten $unit_d = array(1, 60, 3600, 3600*24, 3600*24*7, 3600*24*31, 3600*24*365); |
Berechnung.
Jetzt beginnt die eigentliche Berechnung und Generierung der Ausgabe. Das Skript baut seine Ausgabe in der Variablen $return zusammen. Zunächst interessiert einmal die Frage: Liegt das Ereignis $ts in der Vergangenheit oder in der Zukunft? Wenn es in der Vergangenheit liegt, ist $tdiff positiv, ansonsten negativ. Die Ausgabe beginnt mit ‘vor’ bzw ‘in’ [...soundsoviel Zeiteinheiten]:
13 14 | // Liegt Ereignis in Vergangenheit oder Zukunft? $return = ($tdiff > 0) ? 'vor ' : 'in '; |
Ab jetzt stören uns negative Zahlen nur noch. Ich setze $tdiff auf seinen positiven Absolutbetrag.
15 16 | // Absolutwert der Zeitdifferenz $tdiff = abs($tdiff); |
Jetzt kommt was Wesentliches. Da wir nicht wissen, ob die Zeitdifferenz Sekunden oder Jahre beträgt, tasten wir uns mit Hilfe der Sekunden-Vielfachen aus $unit_d durch eine Schleife, bis wir die Zeiteinheit in der richtigen Größenordnung gefunden haben. Wer mit dem folgenden Code nicht zurechtkommt, akzeptiert in einfach als funktionierend
17 18 19 20 21 22 23 24 | $i=0; // hochzählen bis zur passenden Größenordnung for($j=0; $j<count($units); $j++) { if($tdiff > $unit_d[$j]) { $i++; } } $i--; // ...whatever! |
Die Variable $i zeigt jetzt auf die Stelle in den Arrays, die die sinnvolle Zeiteinheit für unsere Zeitdifferenz ist.
So. Und jetzt wirds abgefahren. Je größer ein Zeitraum ist, desto weniger genau müssen wir ihn nehmen. Wenn etwas vor 4 Monaten geschehen ist, spielen die Sekunden in der Regel keine Rolle mehr! Wir wollen deshalb nur jeweils zwei Zeiteinheiten anzeigen, also z.B. “3 Minuten und 35 Sekunden” oder “2 Wochen und 3 Tage”. Und das geht so:
- Der Wert der ersten Zeiteinheit ist die Zeitdifferenz (in Sekunden) geteilt durch den Multiplikator “unserer” Zeiteinheit, das ganze abgerundet. (Zeile 26).
- Wir geben aus: Den Zahlenwert, gefolgt von dem Namen der Zeiteinheit (Zeile 27)
- …falls der Zahlenwert größer als 1 ist, hängen wir den Pluralteil an (Zeile 28).
- Der Wert der zweiten Zeiteinheit ist der REST der ganzzahligen Division der Zeitdifferenz durch den Zeiteinheits-Multiplikator. Das ganze noch dividiert durch den Zeiteinheits-Multiplikator der nächstkleineren Zeiteinheit. Und abgerundet. Schokiertes Schweigen? Zeile 29!
- Die Ausgabe für die zweite Zeiteinheit ist die selbe wie die für die Erste - nur dass wir sie nur dann ausgeben, wenn sie größer als null ist (Zeile 30).
- Fertig!
25 26 27 28 29 30 31 32 33 34 | // "This is where the magic happens!" ;-) $u1 = floor($tdiff/$unit_d[$i]); $return .= " {$u1} {$units[$i]}"; $return .= ($u1>1) ? $unit_p[$i] : ""; $u2 = floor(($tdiff%$unit_d[$i])/$unit_d[$i-1]); if($u2 > 0) { $return .= " und {$u2} {$units[$i-1]}"; $return .= ($u2>1) ? $unit_p[$i-1] : ""; } return $return; |
“Das wars auch schon”. Für alle die das nicht nachbauen, sondern einfach nur benutzen wollen, gibts das Skript hier fertig zur freien Verwendung!
Download
Download gibbonweb’s timesince()
Wer es noch verbessern möchte ist in den Kommentaren dazu eingeladen!
Tags: code, datum, php, zeitberechnung
Hi, deine for-Schleife mit dem nachfolgenden, etwas obskuren $i–, kannst du in eine while-Schleife umwandeln ohne eine zusätzliche Lauf-Variable $j
Statt:
for($j=0; $j $unit_d[$j]) {
$i++;
}
}
$i–; // …whatever!
das hier:
while(isset($unit_d[$i+1]) && $tdiff > $unit_d[$i+1]) {
$i++;
}
Ach so, ansonsten natürlich sehr schön. Danke!
Hello! Please e-mail me your contacts. I have a question webmaster@bravto.ru” rel=”nofollow”>……
Thank you!!!…
Medicamentspot.com International Legal RX Medications. Special Internet Prices (up to 40% off average US price). NO PRIOR PRESCRIPTION REQUIRED!…
Combivir@buy.online” rel=”nofollow”>.…
Buy:100% Pure Okinawan Coral Calcium.Petcam (Metacam) Oral Suspension.Prednisolone.Actos.Nexium.Prevacid.Arimidex.Valtrex.Zyban.Mega Hoodia.Human Growth Hormone.Lumigan.Retin-A.Accutane.Synthroid.Zovirax….
Buy:Propecia.Cialis.Viagra Super Force.Cialis Soft Tabs.Soma.Maxaman.Super Active ED Pack.Zithromax.Tramadol.Cialis Super Active+.VPXL.Levitra.Viagra Professional.Viagra Soft Tabs.Viagra Super Active+.Cialis Professional.Viagra….
Buy:Zetia.Lipitor.Aricept.Seroquel.Benicar.Wellbutrin SR.Lipothin.Zocor.Cozaar.Amoxicillin.Female Cialis.Acomplia.Lasix.Prozac.Advair.Buspar.Female Pink Viagra.Nymphomax.Ventolin.SleepWell….
Finder http://cgeyho.AUTOPARTSVILLE.INFO/tag/telescope+finder+Finder/ : Finder…
Finder…