PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zeitmessung und Zeitausgabe


Don Stefano
01.04.2005, 19:02:01
Hallo zusammen,

Ich programmiere eine Art Quizsystem mit verschiedenen Aufgaben- und Fragenblöcken.

Ein Teil dieser Aufgaben soll unter Zeitbegrenzung funktionieren. Das heißt man darf für z.B. eine Reihe von 20 oder 30 Aufgaben max. nur 20 Minuten Zeit haben. Danach muss das Ganze abbrechen.

Ich weiß schon, dass dies mit php nicht automatisch geht, aber zumindest kann man ja die Zeit messen, und wenn die 20 Minuten vergangen sind, beim nächsten Klick dann abbrechen.

Vor einiger Zeit hat mir dazu schon mal ein "Bob" einen Ratschlag erteilt.

<?
session_start();
if (!isset($_SESSION['start_time'])) {
$_SESSION['start_time'] = time();
} elseif ($_SESSION['start_time']+1200 <= time()) {
die('zeit abgelaufen');
}


Wenn also die Vorgabeseite immer wieder aufgerufen wird, müßte ja somit nach 20 Minuten Ende sein und das Skript abbrechen.

Es soll nun aber bei jeder Aufgabe auch die verbleibende Zeit angezeigt werden in der Form: "Sie haben noch 13:21 Min. Zeit". Und dann bei der nächsten Aufgabe z.B. "Sie haben noch 11:45 Min. Zeit". usw.

Weiß vielleicht jemand, wie ich dies bewerkstelligen kann zusammen mit der oben skizzierten Vorgehensweise der Zeitmessung (Timer) ?

Herzlichen Dank
Don Stefano

Opendix
01.04.2005, 20:55:41
dukannst ja einfach die differenz der beiden timestamps ausrechnen und daraus minuten machen...

du hast ja startzeit und endzeit (+1200) dann kanns tbbei jedem klick eifnach die zeitangabe mit +1200 - den startwert rechnen das ganze durch 60 und der rest sind dann noch die sekunden :)

frag mich, ob man das kappiert^^

Don Stefano
02.04.2005, 00:41:53
Ja danke, ich kapiere das grundsätzlich schon.

Aber habe ich denn dann ein Ergebnis in Sekunden? Oder anders gefragt:

Angenommen der Timer startet um 12:00 Uhr. Würde ich dann rechnen (?):


$zeit = (($_SESSION['start_time']+1200 - $_SESSION['start_time'])/60);

Und da käme dann eine Sekundenangabe wie z.B: $zeit = 990/60 = 16,5 Min. ?


Ich kann mir das nicht vorstellen, weil z.B: 12:00 doch keine Angabe in Sekunden ist oder doch ? Oder entspricht 12:00 dann einfach 43200 ? (also 12 Stunden x 60 Minuten x 60 Sekunden ?

Dankeschön
Don S.

CrAnE
02.04.2005, 00:48:15
Wenn ich mich nicht total irre arbeitetest du doch mit timestamps oder? Ein timestamp ist nur eine lange nummr die die sekunden angibt die seit (frag mich nicht wann) vergangen sind... du kannst sie also ohne probleme ovneinander abzien ;)

Don Stefano
02.04.2005, 01:23:43
Wenn time() den sogenannten "Timestamp" liefert, dann hast Du völlig recht.

Jetzt kann ich mir also sicher sein, dass meine Vermutung richtig war!
(Die Profis mögen mir meine teilweise vermutlich wirklich doofen Fragen bitte nachsehen) ;-)

Tante Grazie
Don Stefano

CrAnE
02.04.2005, 01:29:32
time() gibt den timestamp zurück. wenn du nun wissen willst wielange derjenige noch zeit hat musst du die startzeit von der jetztigen zeit abziehen also

$ueber = $startzeit - time();

nun hast du die zeit in sekunden die noch über sind.. die musst halt dann noch umwandeln wenn du das willst...

mfg Crane

|Coding
02.04.2005, 15:44:57
Ein timestamp ist nur eine lange nummr die die sekunden angibt die seit (frag mich nicht wann) vergangen sind...
Der Unix-Timestamp, von dem hier die rede ist, hat am 1.1.1970 um 00:00:00 GMT begonnen. Das war der Beginn der Unix-Epoche.

time() gibt dir also den Unix-Zeitstempel (Timestamp) in Sekunden, seit 1.1.1970 00:00:00 GMT zurück.

CrAnE
02.04.2005, 17:35:10
Danke für deine verbesserung Coding ;) hatte das datum nicht mehr im kopf :P

|Coding
02.04.2005, 17:38:46
Ja, ja. "Vergessen", sicher doch *gg*

CrAnE
02.04.2005, 17:40:25
habe es schonmal gelesen aber habe besseres zu tuen als mir son datum zu merken :P habe ja auch gesagt "zählt die sekunden seit irgendwan" :D

Don Stefano
05.04.2005, 00:42:56
Ohje ich habe dabei zuerst gar nicht verstanden, dass $_SESSION['start_time'] auch ein Zeitstempel ist. Wohl derjenige zu der Zeit wenn die Session gestartet wird.

Nun habe ich aber das Problem, dass die Session nicht unbedingt zu der gleichen Zeit gestartet wird, wie das Quiz. Mit Start der Session betritt man die Seite und kann sich auch erst einige Minuten dort alles ansehen, Anleitungen lesen usw.

Erst wenn man das eigentliche Quiz startet, muss die Startzeit festgelegt werden. Aber in diesem Moment wird eben keine Session gestartet.

Jetzt ist es wohl logisch dass ich statt dem Zeitstempel $_SESSION['start_time'] einfach time () verwenden muss um die Startzeit zu ermitteln.

Damit ich dann damit rechnen kann müßte es z.B. folgendermaßen aussehen:


$startzeit = time();
if $startzeit+1200 <= time()) {
die('zeit abgelaufen');

Das Problem ist aber nun, dass dieses Skript mit jeder Aufgabe immer wieder aufgerufen wird (erst das Vorgabeskript - dann mittels post ein Saveskript - dann wieder das Vorgabeskript usw.) Das bedeutet aber auch, dass $startzeit mit jedem Aufruf der Seite wieder neu deklariert wird - und dann macht es natürlich keinen Sinn mehr.

Wie kann ich es einrichten, dass $startzeit mittels time() nur ein einziges Mal definiert wird, und bei den folgenden Aufrufen der Seite nicht mehr ?

Ich könnte natürlich an den Link, der die Seite zum ersten Mal aufruft eine Variable anhängen, z.B. vorgabeskript.php?beginn=1 und diese dann mit get und "if isset $beginn" abfragen.

Aber gibts nicht noch eine elegantere und sicherere Lösung ?

Danke für eure Hilfe (wie immer)
Don

|Coding
05.04.2005, 00:58:55
Speichere den Unix-Timestamp mit der IP des Users zusammen in eine Datenbank und gut ist. Die kann dann auch keiner manipulieren.

Don Stefano
05.04.2005, 13:43:58
Das klingt nach einer guten Idee. Aber wozu brauche ich die Ip des Users ?

Reicht es dann nicht auch den Zeitstempel zusammen mit der Userid zu speichern?

Und damit die dann nicht bei jedem Aufruf der Seite erneut gespeichert wird, frage ich ab, ob in der Zelle "timestamp" bei user "userid" bereits ein Wert steht?

Gute Anregung, nur wozu die IP ?

Gruß
Don

|Coding
05.04.2005, 14:02:30
Statt der IP kannst Du auch die Userid nehmen.

Don Stefano
05.04.2005, 17:24:13
Ich muss noch einmal nachfragen, denn ich bin nun zwar weiter gekommen, aber es funktioniert noch nicht richtig. Und ich bin am Ende meines Latein - habe keine Ahnung was falsch läuft:



//Zuerst wird ueberprueft, ob in der tabelle bereits die Startzeit //gespeichert ist. Wenn nicht geschieht dies nun

$result = $db->query("SELECT start FROM $ergebnis WHERE besitzerid='$besitzerID'");
$row = $result->fetch_object();
$startzeit = $row->start;


if($startzeit = 0 || empty($startzeit)) {
$startzeit = time();
$db->query("update $ergebnis SET start='$startzeit' where besitzerid='$besitzerID'");
if ($db->errno) die (mysqli_error($db));
}

//jetzt folgt die Berechnung der verbleibenden Minuten und Sekunden zur Anzeige auf dem Bildschirm
$restzeit = $startzeit+1200 - time();
$minuten = $restzeit/60;
$sekunden = $restzeit%60;


echo "es verbleiben: ".$minuten.".".$sekunden." <br>";



Beim ersten Aufruf der Seite scheint es zu klappen. Zumindest erhalte ich die Ausgabe:

es verbleiben: 20.0

Aber beim zweiten Aufruf der Seite klappt es nicht mehr. Dann erscheint die folgende Ausgabe:

es verbleiben: -18545211.883333.-53

Und somit klappt dann auch nicht die Abfrage

if ($startzeit+1200 <= time()) {
die('zeit abgelaufen');
}


Diese führt nämlich beim zweiten Durchlauf (also bereits nach wenigen Sekunden) zum Abbruch mit der Meldung:

zeit abgelaufen
und nicht erst nach 20 Minuten wie geplant.

Ich vermute, dass irgendwie der Zeitstempel aus der Datenbank nicht richtig ausgelesen wird. Aber was da genau falsch läuft weiß ich leider nicht. Liegt es vielleicht am Variablentyp oder der Kollation in der Datenabnk ?

Wer kann mir noch einmal weiterhelfen ?

Gruß
Don Stefano

|Coding
05.04.2005, 17:59:26
if($startzeit = 0 || empty($startzeit)) {
Doch wohl eher:
if($startzeit == 0 || empty($startzeit)) {

Don Stefano
05.04.2005, 18:49:04
Vielen lieben Dank Coding!

Ohne Dich wäre ich aufgeschmissen! Jetzt funktioniert es.

Gruß
Don

|Coding
05.04.2005, 19:06:03
Was wäre die Welt nur ohne mich *g*