Schaltjahr wird falsch berechnet

Hallo Gemeinde.

Ich bin ziemlicher Ardunio Neuling und versuche mal hier mein Glück.
Ich bastel an einem kleine NTP Server der die Arduino Systemzeit die ich über eine http Oberfläche stellen kann hostet.

Dazu verwende ich diesen Sketch:NTP Time Server - Networking, Protocols, and Devices - Arduino Forum

Allerdings ist der Schaltjahrteil buggy:

const uint8_t daysInMonth [] PROGMEM = {
  31,28,31,30,31,30,31,31,30,31,30,31 }; //const or compiler complains

const unsigned long seventyYears = 2208988800UL; // to convert unix time to epoch

// NTP since 1900/01/01
static unsigned long int numberOfSecondsSince1900Epoch(uint16_t y, uint8_t m, uint8_t d, uint8_t h, uint8_t mm, uint8_t s) {
  if (y >= 1970)
    y -= 1970;
  uint16_t days = d;
  for (uint8_t i = 1; i < m; ++i)
    days += pgm_read_byte(daysInMonth + i - 1);
  if (m > 2 && y % 4 == 0)
    ++days;
  days += 365 * y + (y + 3) / 4 - 1;
  return days*24L*3600L + h*3600L + mm*60L + s + seventyYears;
}

Schaltjahre werden hier wohl falsch berechnet, denn ab dem 1.1.87 ist immer ein Tag in der Zukunft und ich glaub ab dem 1.1.21 passet es wieder um dann aber ein paar Jahre später falsch zu gehen.

Leider übersteigt der Code mein Verständniss. Jetzt hatte ich gehofft, das hier einer mehr Durchblick hat was den hier flasch ist?

Schon mal vielen Dank im Voraus :slight_smile:

Warum möchtest du eine Funktion verwenden, welche doch offensichtlich falsch rechnet?

Was hält dich davon ab, was funktionierendes zu verwenden?
z.B. die TimeLib des Herren Paul Stoffregen

Hi,

danke für die Antwort.

Welche Funktion in der Time.h soll ich denn verwenden um den ntp timestamp mit richtigen Schaltjahr-Berechnung zu bekommen? Ich sehe ehrlich gesagt nicht wie mir da die TimeLib.h hilft ... :frowning:

HoerMirAuf:
Leider übersteigt der Code mein Verständniss. Jetzt hatte ich gehofft, das hier einer mehr Durchblick hat was den hier flasch ist?

Du kopierst irgendeinen nicht funktionierenden Mist und hoffst jetzt darauf, dass wir es richten?!

Du kannst vermutlich zählen. Was hält Dich davon ab, eine verhältnismäßig simple Rechnerei selbst durchzuführen?

Gruß

Gregor

Hi,

ich habe deine Frage nicht verstanden. :frowning:

Es gibt doch die Schaltjahrregel:

Ein Jahr ist ein Schaltjahr, wenn es
a) ohne Rest durch vier teilbar ist,
b) aber es ist KEIN Schaltjahr, wenn ohne Rest durch 100 teilbar ist
c) es ist ein Schaltjahr, wenn es ohne Rest durch 400 teilbar ist.

Beispiel: 2020 / 4 = 505, also ein Schaltjahr (Regel a)
1900 / 100 = 19, also KEIN Schaltjahr (Regel b)
2000 / 400 = 5, also Schaltjahr (Regel c)

Es soll eigentlich nicht schwierig sein, diese Regeln zu programmieren...

Gruß Harald

Wenn Du / durch % (Modulo) ersetzt und den Rest (das Ergebnis) abprüfst, wird ein Programmierkonstrukt draus. Das / geht immer und ist damit programmtechnisch nicht zielführend.

Gruß Tommy

Die 100 bzw 400 Jahre Regel kann man auch auslassen wenn man Jahre von 1901 bis 2099 braucht.

Grüße Uwe

Vorsicht! Solche ähnlichen Annahmen führten zum Jahr 2000-Problem. Wir wollen doch nicht ein neues Problemjahr entwickeln, zumal die Berechnung einfach ist.

Gruß Tommy

Hallo Leute!

Vielen Dank für die Hinweise! Jetzt hab ich's kapiert.
Das mit der Modulo Sache und der Schaltjahrregel hat den Durchbruch gebracht.

In dem Codeschnipsel den ich gepostet hatte, hatte der Autor zum einen nicht die 400 100 Regel berücksichtigt und auch schon ganz am Anfang die 1970 aus dem Jahr herausgerechnet und erst danach mit Modulo %4 geprüft ... da kann nur murks raus kommen. Wie er versucht die Anzahl der seit 1970 vergangenen Schaltjahre zu brücksichtigen um den aktuelle Tagesanzahl zu bekommen ist mir auch ein Rätsel.

Wie auch immer, dank Euch frage ich das aktuelle Jahr (Monat > Ferbruar) mit "if/else if" auf Schaltjahr ab und dasselbe nochmal für die bisherigen erfolgten Jahre (for Schleife) seit 1970 bis zum aktuellem Jahr.

Super funzt jetzt genauso wie es soll !!

DANKE !!

Hi

Naja - so Murks ist Das gar nicht.
Seit 1970 sind die Schaltjahr recht regelmäßig - und ohne Lücke (2000 war wegen c) ebenfalls Schaltjahr).
Somit sind die Tage der Jahre und der 4-er Jahre bekannt.
Damit komme ich ziemlich genau auf die Tage bis zum Anfang des aktuellen Jahr.
Und auch dort ist Es kein größeres Hexenwerk, auf die Tagesnummer des Jahres zu kommen.
Mal 24 ... Stunden
Plus Stunden (seit 0 Uhr) Heute
Mal 60 ... Minuten
Plus Minuten (seit voller Stunde) Heute
Mal 60 ... Sekunden
Plus Sekunden (seit voller Minute) Heute
... tadaa ... ich habe fertig und die Sekunden seit 1.1.1970 in der Hand.

Nicht Alles, was man nicht durchblickt, ist Murks ... oder - etwas schlimmer für den Beschuldigten - Hexerei!

MfG