PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Kalender und RTC



Cysign
29.03.2015, 00:26
Hallo zusammen,
ich spiele grade zum ersten Mal mit einem RTC rum und kann mir noch nicht so ganz vorstellen, wie ich ein Intervall bestimme.
Ich würde meinen Arduino gerne in den Tiefschlaf schicken und bei jedem Wachwerden das Intervall seit der letzten Aktion prüfen. Hierbei kann es sich durchaus mal um Tage handeln.

Vom RTC bekomme ich einen Wochentag, das Datum, sowie eine Uhrzeit zurück.
Meine Sorge ist nun der Monatsübergang. Sagen wir, die letzte Aktion soll z.B. 30 Tage zurückliegen. Vom RTC bekomme ich nun den Wert 29.3.15 zurück. Wie kann ich berechnen, wie viele Monate der vorherige Monat hatte?
Grade hinsichtlich Schaltjahren stellt das für mich ein Problem dar.

Ich bin dankbar für jegliche Suchbegriffe und Tips ;)

Sisor
29.03.2015, 10:55
Ich antworte mal mit einem C++-Programm, dass ich eben geschrieben habe.

// Anzahl der vergangenen Tage finden
// Author: sisor
// Free software - no rights reserved

#include <iostream>
using namespace std;

typedef unsigned int uint;

struct datum { uint j; uint m; uint t; };

inline bool schaltjahr(uint j){
return (j % 4 == 0 && j % 100 != 0 || j % 400 == 0);
}

uint vergTage(datum alt, datum akt){
uint monate[] = { 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 };
uint vergTage = 0;
uint j = alt.j, m = alt.m, t = alt.t;
monate[1] = schaltjahr(j) ? 29 : 28;
while (j != akt.j || m != akt.m || t != akt.t) {
vergTage++;
t++;
if (t > monate[m - 1]) {
t = 1;
m++;
if (m > 12) {
m = 1;
j++;
monate[1] = schaltjahr(j) ? 29 : 28;
}
}
}
return vergTage;
}

int main() {
datum akt;
akt.j = 2014;
akt.m = 3;
akt.t = 29;

datum alt;
alt.j = 2010;
alt.m = 3;
alt.t = 29;

cout << "Vergangene Tage: " << vergTage(alt, akt) << endl;

cin.get();
return 0;
}

Ausgabe:
Vergangene Tage: 1461

Klebwax
29.03.2015, 12:55
Vom RTC bekomme ich einen Wochentag, das Datum, sowie eine Uhrzeit zurück.
Meine Sorge ist nun der Monatsübergang. Sagen wir, die letzte Aktion soll z.B. 30 Tage zurückliegen. Vom RTC bekomme ich nun den Wert 29.3.15 zurück. Wie kann ich berechnen, wie viele Monate der vorherige Monat hatte?
Grade hinsichtlich Schaltjahren stellt das für mich ein Problem dar.

Deswegen verwendet man eigentlich auch die Unix-Zeit (https://de.wikipedia.org/wiki/Unixzeit). Nur zum Anzeigen oder zur Eingabe wird in ein menschenlesbares Format umgerechnet. Die dazu notwendigen Funktionen sind in der libc vorhanden.

MfG Klebwax

WL
29.03.2015, 14:07
Ich habe so etwas für meine ATZ-Uhr gebraucht:



Lcdat 6 , 1 , "Noch " ; Str(tagerest) ; " Tage "
Lcdat 7 , 1 , Str(stundenrest) ; "Std. " ; Str(minutenrest) ; "Min. " ; Str(sekundenrest) ; "Sek. "

'_________________________________________________ ________________________________________

Function Zeitdiff() As Long 'Errechnet die Zeitdifferenz zwischen zwei Zeitpunkten in Sekunden
Zeitdiff = 0
Schalttag1 = 0
Schalttag2 = 0
'
'----- Zaehlen der Sekunden seit Tagesbeginn ------
Sek1 = Sekunde 'Sekunden
Sek2 = Sekunde_end
'
Temp1a = Minute * 60
Sek1 = Sek1 + Temp1a 'Minuten
Temp2a = Minute_end * 60
Sek2 = Sek2 + Temp2a

Temp1a = Stunde * 3600
Sek1 = Sek1 + Temp1a
Temp2a = Stunde_end * 3600 'Stunden
Sek2 = Sek2 + Temp2a

'
'----- Speichern der Tage vor einem Monat ---------
Monat12(1) = 0 : Monat12(7) = 181
Monat12(2) = 31 : Monat12(8) = 212
Monat12(3) = 59 : Monat12(9) = 243
Monat12(4) = 90 : Monat12(10) = 273
Monat12(5) = 120 : Monat12(11) = 304
Monat12(6) = 151 : Monat12(12) = 334
'
'----- Berechnen der ganzen Tage seit Jahresbeginn -----
Tag1 = Tag - 1
Monat1 = Monat
Tag1 = Tag1 + Monat12(monat1)
'
Tag2 = Tag_end - 1
Monat2 = Monat_end
Tag2 = Tag2 + Monat12(monat2)
'
'----- Jahreszahl ermitteln -----
Jahr1 = Jahr
Jahr2 = Jahr_end
'
'----- Ermitteln ob im aktuelle Jahr ein Schalttag war ---
If Monat1 > 2 Then
Temp1a = Jahr1 Mod 4 : Temp2a = Jahr1 Mod 100 : Temp1b = Jahr1 Mod 400
If Temp1a = 0 And Temp2a <> 0 Then
Schalttag1 = 1
Elseif Temp1b = 0 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
Temp1a = Jahr2 Mod 4 : Temp2a = Jahr2 Mod 100 : Temp1b = Jahr2 Mod 400
If Temp1a = 0 And Temp2a <> 0 Then 'IF(Jahr2 MOD 4 = 0 AND Jahr2 MOD 100 <> 0) OR Jahr2 MOD 400 = 0 THEN
Schalttag2 = 1
Elseif Temp1b = 0 Then
Schalttag2 = 1
End If
End If
'
'----- Erechnen der Schalttage seit dem Jahre 1 -----
Jahr1 = Jahr1 - 1
Jahr2 = Jahr2 - 1
Temp1a = Jahr1 \ 4 : Temp1b = Jahr1 \ 100 : Temp1c = Jahr1 \ 400
Schalttag1 = Schalttag1 + Temp1a 'Schalttag1 = Schalttag1 +(Jahr1 \ 4) -(Jahr1 \ 100) +(Jahr1 \ 400)
Schalttag1 = Schalttag1 - Temp1b
Schalttag1 = Schalttag1 + Temp1c

Temp2a = Jahr2 \ 4 : Temp2b = Jahr2 \ 100 : Temp2c = Jahr2 \ 400
Schalttag2 = Schalttag2 + Temp2a 'Schalttag2 = Schalttag2 +(Jahr2 \ 4) -(Jahr2 \ 100) +(Jahr2 \ 400)
Schalttag2 = Schalttag2 - Temp2b
Schalttag2 = Schalttag2 + Temp2c


'----- Berechnen der Zeitdifferenz -----
'ZeitDiff = Sek2 - Sek1 +(Tag2 - Tag1 + Schalttag2 - Schalttag1) * 86400 +(Jahr2 - Jahr1) * 31536000

Temp1b = Jahr2 - Jahr1
Temp1b = Temp1b * 31536000

Temp1a = Tag2 - Tag1
Temp1a = Temp1a + Schalttag2
Temp1a = Temp1a - Schalttag1
Temp1a = Temp1a * 86400

Temp2c = Sek2 - Sek1

Zeitdiff = Zeitdiff + Temp1a
Zeitdiff = Zeitdiff + Temp1b
Zeitdiff = Zeitdiff + Temp2c

Tagerest = Secdiff \ 86400

Stundenrest = Tagerest * 86400 'StundenRest = INT(((SecDiff -(TageRest * 86400)) / 3600)
Stundenrest = Secdiff - Stundenrest
Stundenrest = Stundenrest \ 3600

Temp1a = Tagerest * 86400 'MinutenRest = INT(((SecDiff -(TageRest * 86400) -(StundenRest * 3600)) / 60)
Temp1b = Stundenrest * 3600
Minutenrest = Secdiff - Temp1a
Minutenrest = Minutenrest - Temp1b
Minutenrest = Minutenrest \ 60

Temp1c = Minutenrest * 60 'SekundenRest = SecDiff -(TageRest * 86400) -(StundenRest * 3600) -(MinutenRest * 60)
Sekundenrest = Secdiff - Temp1a
Sekundenrest = Sekundenrest - Temp1b
Sekundenrest = Sekundenrest - Temp1c

End Function


Quelle> http://www.antonis.de/faq/progs/tagdiff.bas

Cysign
30.03.2015, 01:10
Danke für euere Hilfe.
Auf die Idee mit der Unix-Zeit hätte ich wohl auch selbst kommen sollen ;)