 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
gandro

Anmeldungsdatum: 18.02.2005 Beiträge: 108 Wohnort: Schweiz
|
Verfasst am: 17.04.2005, 17:12 Titel: Wie realisiere ich eine Uptime Funktion |
|
|
Ich denke der Titel sagt alles. In der QB Monster FAQ steht zwar etwas über die Differenz zwischen zwei Uhrzeiten, aber das funktioniert nicht über Mitternacht.
Ich möchte eine Funktion, welche die Zeit anzeigt, die man bereits im Programm ist, und zwar auf die Sekunde genau.
Kann mir jemand sagen wie ich das in ungefähr machen müsste. Ich peils irgendwie net, hatte vorhin ne Uptime von -11 Sekunden 
Zuletzt bearbeitet von gandro am 17.04.2005, 20:49, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
Leader4
Anmeldungsdatum: 20.01.2005 Beiträge: 99 Wohnort: Leipzig
|
Verfasst am: 17.04.2005, 17:59 Titel: |
|
|
Über das Schlüsselwort TIMER klappt es immer, nur nicht über Mitternacht. Aber ehrlich gesagt: Es dürfte doch nicht allzu oft vorkommen, dass ein Programm genau über Mitternacht benutzt wird.
Ganz einfach wäre es also (nur ein kleines Beispiel):
A = Timer 'muss demnach am Programmanfang stehen
Do
Print Int (Timer - A)
Loop
Über Mitternacht wirds komplizierter. Ich würde es vielleicht so machen:
A$ = Left$(Date$,2) 'ließt aktuelles Datum ein
Timer = A1
[...] 'Programm
Sub Kotrolle
If Left$(Date$,2) <> A$ = Then Summe = Summe + (Timer-A1) ' 1)
Timer = A2
End Sub
Gesamtzeit = Summe + (Timer - A2) '2)
System
1) Rechnet die Zeit bis Mitternacht aus
2) Addiert zur Gesamtzeit die Zeit nach Mitternacht
Im ganzen Programm musst du dann immer wieder zu dieser Sub zugreifen, damit das Programm möglichst schnell registriert, dass ein neuer Tag angebrochen ist.
Dies sind nur kurze Beispielprogramme, ob sie funktionieren hab ich nicht ausprobiert. _________________ Ein richtiger Programmierer muss so richtig faul sein und sich den ganzen Tag mit der Frage beschäftigen, wie man mal wieder etwas einfacher machen kann. |
|
Nach oben |
|
 |
gandro

Anmeldungsdatum: 18.02.2005 Beiträge: 108 Wohnort: Schweiz
|
Verfasst am: 17.04.2005, 18:08 Titel: |
|
|
Danke für die Antwort...
Aber wenn ich das richtig verstanden habe, funktioniert diese Methode auch nur max. 47h 59min lang richtig...
Bei meinem Programm wird aber schon dazu kommen, dass es länger laufen wird...
Gibt es keinen Workaround mit dem ich z.B. am Anfang das Datum und die Uhrzeit speichere und dass das Programm jedesmal wenn ich die Uptime wissen will ausrechnet wie lange es schon läuft? |
|
Nach oben |
|
 |
dreael Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 2529 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 17.04.2005, 18:55 Titel: Der saubere Weg mit Datumsarithmetik... |
|
|
Gehe auf meine Seite
http://www.dreael.ch/Deutsch/Download/DatumBerechnung.html
und downloade die dortigen Datumsarithmetik-Routinen. Nun würde ich das Ganze wie folgt einbinden:
Code: | TYPE Zeitstempel
anzTage AS LONG
anzSekunden AS SINGLE
END TYPE
SUB Jetzt(z AS Zeitstempel)
z.anzSekunden = TIMER
d$ = DATE$
z.anzTage = AnzTageSeit&(VAL(MID$(d$, 4, 2)), VAL(LEFT$(d$, 2)), VAL(RIGHT$(d$, 4)))
END SUB
FUNCTION DifferenzAnzSekunden#(z1 AS Zeitstempel, z2 AS Zeitstempel)
DifferenzAnzSekunden# = 86400# * CDBL(z2.anzTage - z1.anzTage) + CDBL(z2.anzSekunden - z1.anzSekunden)
END FUNCTION
' Hauptprogramm
DIM zsStart AS Zeitstempel, zsSpaeter AS Zeitstempel
' Zu Beginn
Jetzt zsStart
' Hier längere Verarbeitung
' Irgendwann später
Jetzt zsSpaeter
PRINT "Programm läuft seit"; DifferenzAnzSekunden#(zsStart, zsSpaeter); "Sekunden" |
Hinweis: Nur Entwurf, d.h. nicht auf Fehlerfreiheit getestet. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
 |
dreael Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 2529 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 17.04.2005, 19:08 Titel: Ein kleines Problem: Atomares Auslesen |
|
|
QB kennt im Gegensatz zu allen heutigen Betriebssystemen und Programmiersprachen keinen Timestamp-Datentyp, wie ich ihn oben definiert habe. Vor allem ist es nicht möglich, Datum und Uhrzeit als sog. atomare Operation auslesen. QB kann hier übrigens nichts dafür, denn dies rührt bereits von MS-DOS her, wo man für das Auslesen der Zeit auch zwei separate CALL INTERRUPTs (INT 21h/AH=2Ah für Datum, INT 21h/AH=2Ch) benötigt.
Warum dies ein Problem werden kann: Nehmen wir einmal an, dass die Ausführung der Operation
Code: | z.anzSekunden = TIMER |
um 23.59:59.9999 Uhr erfolgt und die Operation
bereits am nächsten Tag um 0.00:00.0001 Uhr. Jeder kann sich nun vorstellen, was passiert: Wir liegen volle 24 h daneben.
Glücklicherweise aber können wir dies mit folgender Methode umrunden:
Code: | d1$ = DATE$
z.anzSekunden = TIMER
d2$ = DATE$
IF d1$ = d2$ THEN
d$ = d1$ ' Wir liegen auf einer völlig unkritischen Zeit
ELSE
' Zeiten sind verschieden, d.h. wir haben genau den Mitternachts-Rollover erwischt
IF z.anzSekunden < 43200! THEN
d$ = d2$ ' Die TIMER-Abfrage erfolgte bereits am neuen Tag
ELSE
d$ = d1$ ' Die TIMER-Abfrage erfolgte noch am alten Tag
END IF
END IF |
Erst mit dieser Änderung arbeitet die Zeitabfrageroutine vollkommen "bullet-proof". :-) _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
 |
gandro

Anmeldungsdatum: 18.02.2005 Beiträge: 108 Wohnort: Schweiz
|
Verfasst am: 17.04.2005, 20:49 Titel: |
|
|
Vielen Dank für die Antworten, ich glaub jetzt sollte es klappen |
|
Nach oben |
|
 |
stef
Anmeldungsdatum: 13.01.2005 Beiträge: 102
|
Verfasst am: 18.04.2005, 10:45 Titel: |
|
|
Und wieder einen neuen Befehl gelernt, denn bisher kannte ich CDBL nicht. Man lernt hier doch immer wieder neues.
Auch wenn es scheinbar zu spät ist will ich mal trotzdem meine Funktion zum Berechnen von Zeitdifferenzen hier reinstellen:
Einfach zum Programmstart Datum und Zeit speichern:
Uhrzeit$ = TIME$
Datum$ = DATE$
Und dann mit der Funktion später die Zeitdifferenz in Sekunden berechnen:
PRINT ZeitDiff (Datum$, Uhrzeit$, DATE$, TIME$)
Die Funktion berrechnet die Zeitdifferenz immer korrekt, selbst wenn dazwischen Jahrhunderte liegen:
Code: | 'Errechnet die Zeitdifferenz zwischen zwei Zeitpunkten in Sekunden
'Parameter: Datum1 -> MM-TT-JJJJ
' Zeit1 -> hh:mm:ss
' Datum2 -> MM-TT-JJJJ
' Zeit2 -> hh:mm:ss
FUNCTION ZeitDiff# (Datum1 AS STRING, Zeit1 AS STRING, Datum2 AS STRING, Zeit2 AS STRING)
DIM Sek1 AS LONG 'Sekunden seit Tagesbeginn
DIM Sek2 AS LONG
DIM Tag1 AS INTEGER 'ganze Tage seit Monatsbeginn
DIM Tag2 AS INTEGER
DIM Monat(1 TO 12) AS INTEGER 'Tage bis zum Monatsbeginn im Jahr
DIM Monat1 AS INTEGER 'Monatsnummer
DIM Monat2 AS INTEGER
DIM Jahr1 AS INTEGER 'Jahreszahl
DIM Jahr2 AS INTEGER
DIM Schalttag1 AS INTEGER 'Anzahl Schalttage seit dem Jahre 1
DIM Schalttag2 AS INTEGER
'----- Z„hlen der Sekunden seit Tagesbeginn -----
Sek1 = VAL(MID$(Zeit1, 7)) 'Sekunden
Sek2 = VAL(MID$(Zeit2, 7))
Sek1 = Sek1 + VAL(MID$(Zeit1, 4, 2)) * 60 'Minuten
Sek2 = Sek2 + VAL(MID$(Zeit2, 4, 2)) * 60
Sek1 = Sek1 + VAL(LEFT$(Zeit1, 2)) * 3600 'Stunden
Sek2 = Sek2 + VAL(LEFT$(Zeit2, 2)) * 3600
'----- Speichern der Tage vor einem Monat -----
Monat(1) = 0: Monat(7) = 181
Monat(2) = 31: Monat(8) = 212
Monat(3) = 59: Monat(9) = 243
Monat(4) = 90: Monat(10) = 273
Monat(5) = 120: Monat(11) = 304
Monat(6) = 151: Monat(12) = 334
'----- Berechnen der ganzen Tage seit Jahresbeginn -----
Tag1 = VAL(MID$(Datum1, 4, 2)) - 1
Monat1 = VAL(LEFT$(Datum1, 2))
Tag1 = Tag1 + Monat(Monat1)
Tag2 = VAL(MID$(Datum2, 4, 2)) - 1
Monat2 = VAL(LEFT$(Datum2, 2))
Tag2 = Tag2 + Monat(Monat2)
'----- Jahreszahl ermitteln -----
Jahr1 = VAL(MID$(Datum1, 7))
Jahr2 = VAL(MID$(Datum2, 7))
'----- Ermitteln ob im aktuelle Jahr ein Schalttag war ---
IF Monat1 > 2 THEN
IF (Jahr1 MOD 4 = 0 AND Jahr1 MOD 100 <> 0) OR Jahr1 MOD 400 = 0 THEN
Schalttag1 = 1
END IF
END IF
IF Monat2 > 2 THEN
IF (Jahr2 MOD 4 = 0 AND Jahr2 MOD 100 <> 0) OR Jahr2 MOD 400 = 0 THEN
Schalttag2 = 1
END IF
END IF
'----- Erechnen der Schalttage seit dem Jahre 1 -----
Jahr1 = Jahr1 - 1
Jahr2 = Jahr2 - 1
Schalttag1 = Schalttag1 + Jahr1 \ 4 - Jahr1 \ 100 + Jahr1 \ 400
Schalttag2 = Schalttag2 + Jahr2 \ 4 - Jahr2 \ 100 + Jahr2 \ 400
'----- Berechnen der Zeitdifferenz -----
ZeitDiff = Sek2 - Sek1 + (Tag2 - Tag1 + Schalttag2 - Schalttag1) * 86400 + (Jahr2 - Jahr1) * 31536000#
END FUNCTION |
Die Funktion hatte ich seinerzeit für den Programmierwettbewerb auf qb-city.de geschrieben. |
|
Nach oben |
|
 |
gandro

Anmeldungsdatum: 18.02.2005 Beiträge: 108 Wohnort: Schweiz
|
Verfasst am: 18.04.2005, 19:58 Titel: |
|
|
danke steff, ich hab jetzt deine variante genommen, da meine eigene immer noch nicht 100%ig funktioniert hat...
PS: ist schon ok, wenn ich sie zusammen mit meinem Programm unter die GPL setze? (solltest du nicht wissen was das ist: siehe hier und hier) |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|