Unix timestamp Differenz in Tagen, Minuten und Sekunden berechnen

Hallo,

ich habe zwei Unix timestamps, z.B. 1501268400000 und 1501087994000.
Die Differenz beträgt 180406000
Nun möchte ich aus der Differenz die Anzahl Tage, Stunden, Minuten, Sekunden ausrechnen.

Herauskommen müsste 2 Tage, 2 Stunden, 6 Minuten, 46 Sekunden

Danke und lieben Gruß,
Chris

Gehen die Uhren auf dem Mond anders?

Unix timestamp

Der Rest sind Grundrechenarten höchstens 3. Klasse.

Gruß Tommy

Hi

~ $ timestamp 1501268400000
21.04.49543 18:00:00 -> 1501268400000

Dafür habe ich eben eine eigene Funktion zusammen gebastelt, Die mir den übergebenen Timestamp in ein Datum umrechnen.

Sicher, daß Du im Jahr 49543 unterwegs bist?

MfG

PS: Mit drei Nullen weniger wird 'ein Schuh draus'
~ $ timestamp 1501268400
28.07.2017 21:00:00 -> 1501268400

~ $ timestamp 1501087994
26.07.2017 18:53:14 -> 1501087994

Eingefügt in der .bash_aliases (Linux)
#date Timestamp in Datum umrechnen
timestamp() {
date -d @$1 "+%d.%m.%Y %H:%M:%S -> %s"
};

postmaster-ino:
Hi

~ $ timestamp 1501268400000
21.04.49543 18:00:00 -> 1501268400000

Dafür habe ich eben eine eigene Funktion zusammen gebastelt, Die mir den übergebenen Timestamp in ein Datum umrechnen.

Schön für Dich. Willst Du diese Funktion für Dich behalten oder sie als Hilfe anbieten?
Grüße Uwe

Hi

Denke, unsere Posts haben sich überschnitten (5-Minuten-Sperre und so).
Ist oben angehangen.
Befürchte aber, daß das Groh damit nicht viel anfangen kann, da Windows als OS.

MfG

themanfrommoon:
ich habe zwei Unix timestamps, z.B. 1501268400000 und 1501087994000.
Die Differenz beträgt 180406000
Nun möchte ich aus der Differenz die Anzahl Tage, Stunden, Minuten, Sekunden ausrechnen.

Herauskommen müsste 2 Tage, 2 Stunden, 6 Minuten, 46 Sekunden

Dass Deine Zahlen keine Unixtimestamps sind, sondern um den Faktor 1000 zu groß, haben ja schon andere geschrieben.

Ansonsten kommt man mit den richtigen Zahlen durchaus hin:

void unixdiff(uint32_t zeit1, uint32_t zeit2) {
uint32_t diff;
uint8_t sec, mi, hr;
  if (zeit1 > zeit2) diff = zeit1 - zeit2;
  else diff = zeit2 - zeit1;
  sec = diff % 60;
  diff /= 60;
  mi = diff % 60;
  diff /=60;
  hr = diff % 24;
  diff /= 24;
  Serial.print(F("Tage: ")); Serial.print(diff);
  Serial.print(F(" Stunden: ")); Serial.print(hr);
  Serial.print(F(" Minuten: ")); Serial.print(mi);
  Serial.print(F(" Sekunden: ")); Serial.println(sec);
}
 
void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  unixdiff(1501268400,1501087994);
}

void loop() {
  
}

Gruß Tommy

Der Rest sind Grundrechenarten höchstens 3. Klasse.

....die 3. Klasse ist lange her :slight_smile:
Wer kann denn in der 3. Klasse C programmieren?

Die Unix Timestamps, die ich habe sind in Millisekunden.
Die Differenzen von beiden Timestamps habe ich ja bereits.
Also geht es nur noch darum aus einer Zahl in Millisekunden die Anzahl ganzer Tage, Stunden, Minuten und Sekunden auszurechnen.

Da steh ich grad n bisschen auf dem Schlauch, wie man das vernünftig löst.
In Excel habe ich es fast hinbekommen, aber eben nur fast. siehe Anhang
Excel macht da irgendwie einen Rundungsfehler?!
30.09.2017 23:23:17 ist als Unix Timestamp: 1506813797000 (in Millisekunden)
28.07.2017 08:00:00 ist als Unix Timestamp: 1501228800000 (in Millisekunden)
Die Differenz beträgt: 5584997000 (in Millisekunden)
Nun teile ich 5584997000 / (2460601000) und erhalte 64,6411689815, das kürze ich auf 64 volle Tage.
Dann rechne ich den Rest von 5584997000 / (24
60601000) aus und teile den durch 60601000.
Da kommt dann 15,3880555555 bei raus, das kürze ich auf 15 volle Stunden.
Dann rechne ich den Rest von 55397000 / (60601000) und teile den durch 601000.
Da kommt dann 23,2833333293 bei raus, das kürze ich auf 23 volle Minuten.
Dann rechne ich den Rest von 1397000 / (60
1000) und teile den durch 1000.
Da kommt dann 17 bei raus, das kürze ich auf 17 volle Sekunden. (bei Excel kommt hier nun 16,9999997559 bei raus, was Excel dann zu 16 kürzt -> Fehler)

Also, Mathe krieg ich noch hin.

Aber wie geht das ganze jetzt möglichst geschickt in C?

Danke und lieben Gruß,
Chris

Unixtime Differenz.zip (6.91 KB)

Dividieren mit Rest gab es schon in der 3. Klasse.

Wer lesen kann, ist klar im Vorteil.
Über Deinem Beitrag habe ich doch die Lösung für UNIX-Timestamps geschrieben. Deine Zahlen sind per Definition keine. Du musst Deine Zahlen durch 1000 teilen.

Gruß Tommy

Hi Tommy,

habe ich gesehen.
Ich habe an meinem Post länger geschrieben als du für deine Antwort gebraucht hast.

Vielen Dank für deine Antwort!
Meine Zahlen sind so wie ich geschrieben habe.
Sie kommen aus einer Datenbank, die nicht auf meinem Mist gewachsen sind, UND das sind die gleichen Zahlen die man mit der Funktion millis() bekommt. Insofern passt das genau. micros() wäre nochmal um den Faktor 1000 größer.

Alles gut, Problem gelöst (hoffentlich, muss ich noch ausprobieren, ich bin aber sehr zuversichtlich) :slight_smile:

Vielen Dank und lieben Gruß,
Chris

Kurzform:

// Wert von "differenz" in Sekunden
Serial.print(differenz  / 86400);       Serial.print(F(" Tage "));
Serial.print((differenz / 3600) % 24);  Serial.print(F(" Stunden "));
Serial.print((differenz / 60) % 60);    Serial.print(F(" Minuten "));
Serial.print(differenz % 60);           Serial.print(F(" Sekunden "));

Gruß Peter

Über Deinem Beitrag habe ich doch die Lösung für UNIX-Timestamps geschrieben. Deine Zahlen sind per Definition keine. Du musst Deine Zahlen durch 1000 teilen.

Jetzt verstehe ich erst was du meinst.
Asche auf mein Haupt.
In der Datenbank ist die "Zahl" als "1506813797000" hinterlegt.
Diese "Zahl" passt aber von der Größe in keine Zahlenvariable rein.
Das meintest du mit "ist keine Zahl".
Ja, hab ich jetzt verstanden.

....ähm und nun?
Mit welchem Variablentyp kann ich die "Zahl" denn auslesen und durch 1000 teilen?
Ich vermute mal als Text und dann die letzten drei Ziffern einfach abschneiden.
Wie macht man das am Besten?

Lieben Gruß,
Chris

Probier mal, ob Du sie in eine uint64_t rein bekommst.
Ist das eine SQL-Datenbank?
Dann kannst Du der auch das Teilen überlassen:
SELECT wert/1000 AS unixtime FROM ...

Ich habe übrigens nicht geschrieben, das ist keine zahl, sondern das ist kein UNIXtimestamp. Ein kleiner aber feiner Unterschied :wink:

Gruß Tommy

Edit: Da fällt mir ein: Du hast doch geschrieben, das wären Werte von millis() oder? Dann sollten sie in uint32_t rein passen.
Dann musst Du bei der Differenzbildung den Überlauf beachten.

Hallo Tommy,

Probier mal, ob Du sie in eine uint64_t rein bekommst.

Hab ich probiert, dann kommt allerdings bei Serial.print folgende Fehlermeldung:

call of overloaded 'print(uint64_t&)' is ambiguous

Ja, das ist schon eine SQL Datenbank, allerdings greife ich nicht auf die Datenbank zu, sondern über eine API bekomme ich ein JSON.
Dieses parse ich und bekomme dann den Wert geliefert.

Lieben Gruß,
Chris

Auf die SQL-Abfrage hast Du keinen Einfluss? Wo kommen die Werte her? Sind das millis-Werte - glaube ich eher nicht?

Die uint64_t musst Du ja nicht ausgeben, da für Dich nur die uint32_t des Wertes / 1000 interessant ist.

Gruß Tommy

Auf die SQL-Abfrage hast Du keinen Einfluss? Wo kommen die Werte her? Sind das millis-Werte - glaube ich eher nicht?

Ich mache keine SQL Abfrage, sondern eine http Abfrage an eine Middleware-API. (development:api:reference [wiki.volkszaehler.org])
Als Antwort kommt dann ein JSON.
Der Timestamp ist im Format: "ms (oder unix): Millisekunden seit 1.1.1970, 00:00 GMT"

Ich habe es jetzt so versucht, ich kriegs nicht hin :frowning:

uint64_t zwischen = data_tuples0[0];         // Variable "LastTimestamp[i]" füllen mit Wert aus JSON (z.B. "1509121688067")
LastTimestamp[i] = zwischen / 1000 ;

Fehler beim Kompilieren

Lieben Gruß,
Chris

Tommy56:
Die uint64_t musst Du ja nicht ausgeben, da für Dich nur die uint32_t des Wertes / 1000 interessant ist.

Genau. Also Sketch aus #5 mit 64-Bit-Variablen gespeist:

const uint64_t ts1 = 1501268400000, ts2 = 1501087994000;

void setup()
{
  Serial.begin(9600);
  Serial.println("Start");
  unixdiff(ts1, ts2);
}

void unixdiff(uint64_t zeit1, uint64_t zeit2) {
  zeit1 /= 1000;
  zeit2 /= 1000;
  uint32_t diff;
  uint8_t sec, mi, hr;
  if (zeit1 > zeit2) diff = zeit1 - zeit2;
  else diff = zeit2 - zeit1;
  sec = diff % 60;
  diff /= 60;
  mi = diff % 60;
  diff /= 60;
  hr = diff % 24;
  diff /= 24;
  Serial.print(F("Tage: ")); Serial.print(diff);
  Serial.print(F(" Stunden: ")); Serial.print(hr);
  Serial.print(F(" Minuten: ")); Serial.print(mi);
  Serial.print(F(" Sekunden: ")); Serial.println(sec);
}

void loop() {}
Tage: 2 Stunden: 2 Minuten: 6 Sekunden: 46

@agmue: Ja, genau so.

Welcher Depp speichert eigentlich Unixtime*1000 (also in ms). Die Frage muss man wirklich mal stellen.

Gruß Tommy

Welcher Depp speichert eigentlich Unixtime*1000 (also in ms). Die Frage muss man wirklich mal stellen.

Das kann ich dir leider nicht beantworten. Das Ganze stammt von hier: http://volkszähler.org/

Ich habe es jetzt so versucht, ich kriegs nicht hin :frowning:

uint64_t zwischen = data_tuples0[0];         // Variable "LastTimestamp[i]" füllen mit Wert aus JSON (z.B. "1509121688067")
LastTimestamp[i] = zwischen / 1000 ;

Fehler beim Kompilieren

Lieben Gruß,
Chris

Nimm die Variante von agmue.

Gruß Tommy

Hallo,

Die Differenzgeschichte ist das eine, da bin ich noch nicht soweit.

An einer anderen Stelle wollte jetzt doch lieber mit Zahlen hantieren.
Sprich, ich möchte aus dem geparsten JSON, welches z.B. den timestamp "1501268400000" durch 1000 teilt (oder die letzten drei Stellen abschneidet) und in eine Zahlenvariable speichert.

Wie sieht denn eine Lösung dafür aus?

Lieben Gruß,
Chris