Forum: Mikrocontroller und Digitale Elektronik Algorithmus für Zeit zw 2 Zeiten


von ???? (Gast)


Lesenswert?

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????

von ???? (Gast)


Lesenswert?

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?!

von Klaus (Gast)


Lesenswert?

Beide Zeite ab einem bel. Jahr(2008) in Sekunden umwandenln
und schauen ob die Zeit dazwischen liegt?

von Bernd M. (bernd_m)


Lesenswert?

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

von ???? (Gast)


Lesenswert?

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!

von Peter D. (peda)


Lesenswert?

???? 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.

von gast (Gast)


Lesenswert?

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...

von holger (Gast)


Lesenswert?

>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.

von Klaus (Gast)


Lesenswert?

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! :)

von ???? (Gast)


Lesenswert?

Ö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 )

von Klaus (Gast)


Lesenswert?

.. alle 4 Jahre ist ein Schaltjahr
   Jahr Modulo 4
mit bekanntem Startjahr sollte Deide Frage geklärt haben.

von ???? (Gast)


Lesenswert?

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???

von Klaus (Gast)


Lesenswert?

... nein

von Peter D. (peda)


Lesenswert?

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

von ???? (Gast)


Lesenswert?

...

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....

von Klaus (Gast)


Lesenswert?

ü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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Klaus (Gast)


Lesenswert?

Sekunden = Monate31 * 31 + Monate30 *30 + Monate2829 28  24 * 3600

von Klaus (Gast)


Lesenswert?

Sekunden = Monate31 * 31 + Monate30 *30 + Monate2829  28  24 * 3600

von gast (Gast)


Lesenswert?

> 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.

von holger (Gast)


Lesenswert?

@ 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 ;)

von Klaus (Gast)


Lesenswert?

such mal im I-Net nach "ewiger Kallender"

es sind Algos zu Dutzenden unterweges.

von Rik (Gast)


Lesenswert?

> 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.

von Ralli (Gast)


Lesenswert?

@ 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
Noch kein Account? Hier anmelden.