Hi, ich muss eine Messung durchführen, wenn die Zeit (die ich über einem RTC geschickt bekomme) zwischen 2 anderen Zeiten liegt. Also z.b. Start: Sekunde, Minute, Stunde, Tag Monat, Jahr Ende: Sekunde, Minute, Stunde, Tag Monat, Jahr Das einzige was mir da einfallen würde wäre, zuerst abzufragen, ob aktuelles Jahr zwischen Start und End-Jahr liegt. Wenn ja dann messen. Wenn nicht, ist aktuelles Jahr = Start-Jahr, dann Frage Monat ab.... Das ganze zieht sich dann bis hin zu Sekunden. Wenn aktuelles Jahr nicht gleich Start-Jahr ist, dann frage ab ob aktuelles Jahr gleich End-Jahr ist. Wenn ja, dann Frage Monat ab ob kleiner usw. bis Sekunden. Der Algorithmus herfür wird mindestens 100 Codezeilen lang, gibt es dafür nicht irgendwie eine elegantere Lösung. Mir fällt dazu gerade aber gar keine andere Variante ein. Jemand eine Idee????
Bei den Monaten muss natürlich nicht nur geschaut werden ob kleiner oder größer, sondern ob Wert dazwischen liegt. z.b. Startjahr 2000 und Startmonat 8 Endjahr 2000 und Endmonat 10 dann dürfte bei aktueller Zeit: Jahr 2000 und Monat 12 auch keine Messung stattfinden, was bedeutet, das der Code wieder extrem viel größer wird. Ist es wirklich für so eine einfache Abfrage nötig, so viel Code zu schreiben?!
Beide Zeite ab einem bel. Jahr(2008) in Sekunden umwandenln und schauen ob die Zeit dazwischen liegt?
Hi, wie wärs damit, die komplette Zeitinfo in ein 32Bit Integer zu umzurechnen und dann mit diesem Ergebnis weiter arbeiten (-> UNIX Zeitformat o.ä.) Gruss Bernd
Boa danke! Ihr seid meine Rettung. Das ist wirklich extrem gescheit, einfach alles in Sekunden umwandeln und dann brauche ich nur einen Vergleich! Habs mir ausgerechnet, mit meinen IF abfragen hätte ich ungefähr 400 IF Anweisungen gebraucht. Danke Leute!
???? wrote:
> Der Algorithmus herfür wird mindestens 100 Codezeilen lang
Also ich komme auf 14 Codezeilen:
1 | #include <stdio.h> |
2 | |
3 | |
4 | struct time { |
5 | uint8_t se; |
6 | uint8_t mi; |
7 | uint8_t ho; |
8 | uint8_t da; |
9 | uint8_t mo; |
10 | uint8_t ye; |
11 | };
|
12 | |
13 | |
14 | struct time start, end, now; |
15 | |
16 | |
17 | uint32_t get_sec( struct time t ) |
18 | {
|
19 | return ((((t.ye * 12UL + t.mo) * 31 + t.da) * 24 + t.ho) * 60 |
20 | + t.mi) * 60 + t.se; |
21 | }
|
22 | |
23 | |
24 | uint8_t dazwischen( void ) |
25 | {
|
26 | uint32_t now_sec = get_sec(now); |
27 | |
28 | return now_sec > get_sec(start) && now_sec < get_sec(end); |
29 | }
|
Peter P.S.: Es reicht, wenn get_sec monoton ist, die Lücken stören also nicht.
Bilde doch die Differenz aus dem gregorianischer Kalender. mit (jeweils 1 und 2): y als Jahr m als monat d als tag
1 | dTage=(y1-y2)*365 + y1 DIV 4 - y2 DIV 4 - y1 DIV 100 + y2 DIV 100 + y1 DIV 400 - y2 DIV 400 |
2 | + (m1*306+5)/10 - (m2*306+5)/10 + (d1-1) - (d2-1); |
Damit solltest du die Differenz in Tage erhalten (inklusive Schaltjahre). (keine Gewähr ;) ) Dann noch die Stunden (std), Minuten (min) und Sekunden (sec) hinzurechen:
1 | dSekunden=dTage*86400 + (std1-std2)*3600 + (min1-min2)*60 + (sec1-sec2) |
Das müsste funktionieren...
>ich muss eine Messung durchführen, wenn die Zeit (die ich über einem RTC >geschickt bekomme) zwischen 2 anderen Zeiten liegt. Liefert die RTC BCD Werte? Dann kannst du die Zeit in z.B. zwei 32 Bit Variablen schieben. Damit reduzieren sich die Vergleiche erheblich.
was "fauleres" hab ich schon lange nicht mehr gesehen. :) > uint8_t se; > uint8_t mi; > uint8_t ho; > uint8_t da; > uint8_t mo; > uint8_t ye; Geiz ist Geil! :)
Öhm ich habe noch eine Frage dazu... Wenn ich das Jahr in Sekunden umrechne, wären das 31 536 000 Sekunden. So jetzt gibt es aber Schaltjahre, das heißt ein Schaltjahr hätte 31 622 400 Sekunden. Muss ich das irgendwie berücksichtigen? Oder soll ich pro Jahr 31556926 Sekunden nehmen (was der Mittelwert wäre: 365 Tage + 5 Stunden + 48 Minuten + 46 Sekunden )
.. alle 4 Jahre ist ein Schaltjahr Jahr Modulo 4 mit bekanntem Startjahr sollte Deide Frage geklärt haben.
Also der Source von Peter Dannegger schaut sehr gut aus, ich glaube so werde ich es wirklich machen. Großes danke. Allerdings hast du 31 * Monate geschrieben, damit gehst du davon aus, das jeder Monat 31 Tage hat... Geht das so einfach???
holger wrote: > Dann kannst du die Zeit in z.B. zwei 32 Bit Variablen > schieben. Damit reduzieren sich die Vergleiche erheblich. Stimmt, der Code wird deutlich kürzer:
1 | uint32_t get_sec( struct time t ) |
2 | {
|
3 | return ((((((((((uint32_t)t.ye<<4) + t.mo)<<5) + t.da)<<5) + t.ho)<<6) |
4 | + t.mi)<<6) + t.se; |
5 | }
|
Es sind dann aber nur 64 Jahre Differenz möglich. Peter
... und wie wandle ich dann die Monate in Sekunden um???? Sollte ich direkt die Jahre in Sekunden umwandeln und dann den Monat mit select case einzeln in 12 abfragen in Sekunden umwandeln??? Sorry jungs, aber mir fällt dazu wieder keine bessere Idee ein....
überleg mal: wieviele Monate gibt es mit 31, 30, 28(29) Tagen ;gild für ein Jahr Sekunden = Monate31 * 31 + Monate30 *30 + Monate2829 28 24 * 3600
Klaus wrote:
> ... nein
Für die vorliegende Aufgabenstellung: Ja, kann man so machen.
Wichtig ist nur, dass sich eine mit der Zeit aufsteigende Zahlenfolge
ergibt. Ob da jetzt Lücken drinn sind oder nicht, spielt keine Rolle.
Peters Verfahren stellt sicher, dass für 00:00:01 am 1. März eine
größere Zahl rauskommt als für den 28.Februar 23:59:59. Mehr braucht es
auch nicht. Niemand verlangt, dass zwischen beiden Zeitpunkten in
Zahlenform nur eine Differenz von 2 liegen muss. Größer reicht schon.
Sekunden = Monate31 * 31 + Monate30 *30 + Monate2829 28 24 * 3600
Sekunden = Monate31 * 31 + Monate30 *30 + Monate2829 28 24 * 3600
> dann den Monat mit > select case einzeln in 12 abfragen in Sekunden umwandeln??? Der Februar hat nicht immer gleich viele Tage ;) Ohne gregorianische Kalender wirst du hin und wieder kräftige Sprünge in deiner Zeitdifferenz bekommen.
@ Peter >> Dann kannst du die Zeit in z.B. zwei 32 Bit Variablen >> schieben. Damit reduzieren sich die Vergleiche erheblich. >Es sind dann aber nur 64 Jahre Differenz möglich. Ich meinte tatsächlich zwei 32 Bit Variablen pro Uhrzeit. Wenn die RTC BCD Code liefert einfach alle Werte in ein eigenes Byte schieben. Also nicht Bits sparen wie du es gemacht hast. Oder ein long long mit 64 Bit wenn der Compiler das mag. Das sollte bis 9999 reichen. Danach interessiert es wohl keinen mehr ;)
such mal im I-Net nach "ewiger Kallender" es sind Algos zu Dutzenden unterweges.
> alle 4 Jahre ist ein Schaltjahr
Das stimmt nicht.
Weiteres Problem: Schaltsekunden sind nicht vorhersagbar, weil die von
den Leuten bei der PTB (?) festgelegt werden.
@ Rik Das macht der IERS in Paris! (Der Internationale-Erd-Dreh-Dienst) ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.