Go Down

Topic: Unix Zeitstempel zu Datum & Uhrzeit umrechnen (Read 2541 times) previous topic - next topic

-Jan-

May 15, 2016, 05:54 pm Last Edit: May 15, 2016, 06:03 pm by -Jan-
Hallo,

ich bin auf der Suche nach einer Funktion, die einen Unix Zeitstempel in ein lesbares Datum und Uhrzeit umwandelt/ umrechnet. Leider konnte ich keine (brauchbare) Funktion im Netz finden.
Eine Libary soll nicht verwendet werden, da diese i.d.R. viele weiteren Extras mit sich bringen und ich den Code verstehen möchte.

Die Datums- und Zeitrechnerei ist mir persönlich zu kompliziert - deshalb bin ich auf der Suche nach einer fertigen Lösung :D
Theoretisch müsste man ja nur die Tage der Monate und Schaltjahre bei der Berechnung berücksichtigen?

Die "beste" Lösung für Datums- und Zeitberechnungen ist doch immer noch der Unix Zeitstempel? Oder gibt es elegantere Lösungen (als Datum -> Unix Zeitstempel -> Datum) um von der aktuellen Uhrzeit XX Minuten abzuziehen? 

Liebe Grüße

ardubu

#1
May 15, 2016, 06:56 pm Last Edit: May 15, 2016, 07:08 pm by ardubu
Wenn du eine RTC mit einer Library nutzt, kannst du dir meist auch die Unixzeit ausgeben lassen und damit rechnen.
Quote
Die "beste" Lösung für Datums- und Zeitberechnungen ist doch immer noch der Unix Zeitstempel? Oder gibt es elegantere Lösungen (als Datum -> Unix Zeitstempel -> Datum) um von der aktuellen Uhrzeit XX Minuten abzuziehen? 
Wenn die Zeit über 0.00Uhr hinaus geht, ja.

ansonsten könntest du die Formel einbauen.

/** Konvertiert gegliederte UTC-Angaben in Unix-Zeit.
 * Parameter und ihre Werte-Bereiche:
 * - jahr [1970..2038]
 * - monat [1..12]
 * - tag [1..31]
 * - stunde [0..23]
 * - minute [0..59]
 * - sekunde [0..59]
 */
unsigned long unixzeit(int jahr, int monat, int tag,
              int stunde, int minute, int sekunde)
{
  const int tage_seit_jahresanfang[12] = /* Anzahl der Tage seit Jahresanfang ohne Tage des aktuellen Monats und ohne Schalttag */
    {0,31,59,90,120,151,181,212,243,273,304,334};

  int schaltjahre = ((jahr-1)-1968)/4 /* Anzahl der Schaltjahre seit 1970 (ohne das evtl. laufende Schaltjahr) */
                  - ((jahr-1)-1900)/100
                  + ((jahr-1)-1600)/400;

  unsigned long tage_seit_1970 = (jahr-1970)*365 + schaltjahre
                      + tage_seit_jahresanfang[monat-1] + tag-1;

  if ( (monat>2) && (jahr%4==0 && (jahr%100!=0 || jahr%400==0)) )
    tage_seit_1970 += 1; /* +Schalttag, wenn jahr Schaltjahr ist */

  return sekunde + 60 * ( minute + 60 * (stunde + 24*tage_seit_1970) );
}

jurs

Die "beste" Lösung für Datums- und Zeitberechnungen ist doch immer noch der Unix Zeitstempel? Oder gibt es elegantere Lösungen (als Datum -> Unix Zeitstempel -> Datum) um von der aktuellen Uhrzeit XX Minuten abzuziehen?  
Auf jeden Fall ist die doppelte Umandlung "Datum -> Unix Zeitstempel" und am Ende wieder "Unix Zeitstempel -> Datum" die langsamste und aufwändigste Art, um XX Minuten von der aktuellen Uhrzeit abzuziehen. Außerdem funktionieren diese Libraries nur mit UTC-Zeit korrekt, und versagen, wenn sie mit Zeitzonen und der amtlichen Zeit eines Landes (z.B. Deutschland) rechnen sollen und während der Subtraktion eine Zeitumstellung stattfindet.

Nehmen wir mal den Tag der Sommerzeitumstellung 2016, amtliche deutsche Zeit:

Drei Minuten nach der Sommerzeitumstellung war es: 27:03.2016 03:03 Uhr

Wie spät war es fünf Minuten vorher?
Korrekte Antwort: es war zwei Minuten vor der Sommerzeitumstellung, also: 27:03.2016 01:58 Uhr

Ich bin mir sicher, die Arduino-Time-Libraries würden hier (falsch!) ausrechnen: 27:03.2016 02:58 Uhr

-Jan-

Hallo,

danke für Eure Anworten. Die RTC lese ich mithilfe einer eigenen Funktion aus, da ich ohne Libs auskommen möchte und nur so verstehen kann, was das Programm da gerade macht :)

Eine Funktion zum Generieren des Unix Zeitstemples hatte ich schon gefunden. Ich war auf der Suche nach einer Funktion, um den Unix Zeitstempel in ein leserliches Datum & Uhrzeit umzuwandeln.

Ich habe mir nochmals Gedanken über mein Problem gemacht und eine Lösung ganz ohne Unix Zeitstempel gefunden. Mal schauen ob noch Probleme auftauchen...

Code: [Select]

void timeBefore10Min (unsigned int year, int month, int day, int hour, int minute){
  minute = minute - 10;
  if (minute < 0){
    minute = 60 + minute % 10 - 10;
    hour--;
    if (hour < 0){
      hour = 23;
      day--;
      if (day < 1){
        month--;
        if (month == 2){
          day = ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) ? 29 : 28);
        } else if (month == 4 || month == 6 || month == 9 || month == 11){
          day = 30;
        } else {
          day = 31;
        }
        if (month < 1){
          month = 12;
          year--;
        }
      }
    }
  }
  Serial.print(day);
  Serial.print('.');
  Serial.print(month);
  Serial.print('.');
  Serial.print(year);
  Serial.print(' ');
  Serial.print(hour);
  Serial.print(':');
  Serial.println(minute);  
}


Die Berechnung der Minute, sofern die Stunde < 0 wird, kann man sich bei dem Zeitraum von 10 Minuten sparen. (Ist nur drinnen, damit ich flexibler für andere Zeiten bin)

Ist es ohne Probleme möglich, dass ich month, ... als byte festlege? Denn der Bereich geht ja von 0 ... 255 und im ungünstigsten Fall haben sie den Wert -1

Bis jetzt läuft alles auf UTC Zeit, aber man weiß ja nie, was noch so alles kommt. Die obige Funktion würde die Zeit ebenfalls falsch ausrechnen, deshalb versuche ich das noch zu ändern.

Grüße

jurs

Das mit den Minuten sieht mir zu kompliziert aus:
Code: [Select]

void timeBefore10Min (unsigned int year, int month, int day, int hour, int minute){
  minute = minute - 10;
  if (minute < 0){
    minute = 60 + minute % 10 - 10;
    hour--;


Änderungsvorschlag "minute"
Code: [Select]

  minute -= 10;
  if (minute < 0)   
  {
    minute +=60;
    hour--;
...
  }



Bis jetzt läuft alles auf UTC Zeit, aber man weiß ja nie, was noch so alles kommt. Die obige Funktion würde die Zeit ebenfalls falsch ausrechnen, deshalb versuche ich das noch zu ändern.
Wenn "alles" auf UTC-Zeit läuft, sehe ich bei der Berechnung kein Problem

Go Up