Forum: PC-Programmierung [C++] Umrechnung Datum in Timestamp


von Dennis S. (eltio)


Lesenswert?

Hallo zusammen,
folgende Situation: ich berechne aus den Komponenten "Jahr", "Monat", 
"Tag", "Stunde", "Minute" und "Sekunde" einen Timestamp.
1
auto foo = static_cast<int64_t>(std::mktime(timeinfo));

Problem: time_t ist auf meiner Entwl.-Maschine 64 Bit und auf dem Target 
32 Bit. Das händische Umrechnen scheint mit aufgrund Schaltjahre etc. 
fehlerträchtig. Hat jemand eine Idee?

Gruß

von Dirk B. (dirkb2)


Lesenswert?

Am Wert ändert sich doch nichts, egal ob 64 oder 32 Bit.
Die Sekunden sind dieselben.

Probleme bekommst du erst 2038: 
https://de.wikipedia.org/wiki/Unixzeit#Jahr-2038-Problem

von Dennis S. (eltio)


Lesenswert?

Dirk B. schrieb:
> Am Wert ändert sich doch nichts, egal ob 64 oder 32 Bit.
> Die Sekunden sind dieselben.
>
> Probleme bekommst du erst 2038:
> https://de.wikipedia.org/wiki/Unixzeit#Jahr-2038-Problem

Genau das. Daher die 64 Bit.

von Mark B. (markbrandis)


Lesenswert?

Dennis S. schrieb:
> Genau das. Daher die 64 Bit.

Dafür muss die Zielhardware bzw. das Ziel-Betriebssystem auch 
Zeitstempel mit 64 Bit unterstützen.

: Bearbeitet durch User
Beitrag #6499508 wurde vom Autor gelöscht.
von (prx) A. K. (prx)


Lesenswert?

Dennis S. schrieb:
>> Probleme bekommst du erst 2038:
>
> Genau das. Daher die 64 Bit.

Wobei man ja nicht unbedingt am 1.1.1970 anfangen muss. Mit einem 
konstanten Offset zum 1.1.2020 hat man wieder 50 Jahre gewonnen.

Freilich kann man bei knappen Ressourcen überlegen, ob man eine solche 
Sekunden-seit-Irgendwann Timestamp wirklich benötigt, oder ob man 
trennt. Datum/Uhrzeit verbleiben dann im darstellungsfreundlichen 
J/M/T/H/M/S Format, während ein davon unabhängiger Zähler für sowas 
Timeouts zuständig ist - da sind dann auch Millisekunden kein Problem.

Der gepackte FAT-Zeitstempel verwendet 16 Bits fürs Datum und 16 Bits 
für die Uhrzeit, und reicht bei einer Auflösung von 2 Sekunden bis ins 
Jahr 2147, wenn man bei 2020 anfängt.

: Bearbeitet durch User
von foobar (Gast)


Lesenswert?

> Hat jemand eine Idee?

Wo ist denn überhaupt dein Problem?

von (prx) A. K. (prx)


Lesenswert?

Schreibt er doch: Beim Umrechnen von 64 Bits in 32 Bits. ;-)

von Bauform B. (bauformb)


Lesenswert?

Dennis S. schrieb:
> time_t ist auf meiner Entwl.-Maschine 64 Bit und auf dem Target
> 32 Bit.

Musst du denn time_t benutzen? Dein foo ist doch kein time_t? Nimm einen 
eigenen Typ wie uint32_t, der reicht von 1970 bis 2100. Da passt jedes 
vernünftige Ergebnis von mktime() rein, egal, ob 32 oder 64 Bit. Der 
Rest des 32-Bit-Programms läuft damit immerhin schon bis 2100.

Ein anderer Offset als 1970 scheint mir mindestens genauso "gefährlich" 
zu sein wie ein selbstgebasteltes mktime().

von foobar (Gast)


Lesenswert?

>> Wo ist denn überhaupt dein Problem?
>
> Schreibt er doch: Beim Umrechnen von 64 Bits in 32 Bits. ;-)

;-)

Ich versteh sein Problem aber nicht.  Er castet extra nach 64 Bit. 
Damit kann er auf beiden Platformen weiterarbeiten, auf dem Target evtl 
etwas ineffizient, aber es geht.  Will er es möglichst optimal, weiß er 
bereits, dass er time_t benutzen kann.  Was für Ideen erwartet er denn 
noch?

von Mark B. (markbrandis)


Lesenswert?

(prx) A. K. schrieb:
> Schreibt er doch: Beim Umrechnen von 64 Bits in 32 Bits. ;-)

Das geht ohne Probleme. Man braucht nur einen Algorithmus mit 50% 
Kompressionsrate. ;-)

von Rolf M. (rmagnus)


Lesenswert?

(prx) A. K. schrieb:
> Schreibt er doch: Beim Umrechnen von 64 Bits in 32 Bits. ;-)

Nein, sein Problem besteht darin, dass er eine Plattform hat, wo 
mktime() nur 32 Bit zurückgibt und er es deshalb nicht benutzen kann, 
aber er möchte es nicht selbst nachprogrammieren. Also fragt er nach 
Alternativen.

: Bearbeitet durch User
von Mark B. (markbrandis)


Lesenswert?

Rolf M. schrieb:
> Nein, sein Problem besteht darin, dass er eine Plattform hat, wo
> mktime() nur 32 Bit zurückgibt und er es deshalb nicht benutzen kann,
> aber er möchte es nicht selbst nachprogrammieren. Also fragt er nach
> Alternativen.

Nun, was spricht dagegen eine 64-Bit Variante mktime64() mit zu 
kompilieren und zu verwenden?

https://stackoverflow.com/questions/7914368/64-bit-unix-timestamp-conversion

von (prx) A. K. (prx)


Lesenswert?

Vielleicht ist es ihm gelungen, als Target eine Plattform zu finden, die 
keine 64-Bit Integers kennt. Viel Info hat er ja nicht geliefert.

: Bearbeitet durch User
von Dirk B. (dirkb2)


Lesenswert?

Dennis S. schrieb:
> Das händische Umrechnen scheint mit aufgrund Schaltjahre etc.
> fehlerträchtig.

Hast du denn mal den verlinkten Wikipedia-Artikel angesehen?

> Hat jemand eine Idee?

Da sind zwei Funktionen zur Umrechnung drin-

von Dennis S. (eltio)


Lesenswert?

Rolf M. schrieb:
> Nein, sein Problem besteht darin, dass er eine Plattform hat, wo
> mktime() nur 32 Bit zurückgibt und er es deshalb nicht benutzen kann,
> aber er möchte es nicht selbst nachprogrammieren. Also fragt er nach
> Alternativen.
So sieht es aus. Danke für die präzise Erklärung. ;-)

Mark B. schrieb:
> Nun, was spricht dagegen eine 64-Bit Variante mktime64() mit zu
> kompilieren und zu verwenden?
An sich wäre das Verwenden einer kleinen Bibliothek oder ähnliches 
legitim.

Dirk B. schrieb:
> Hast du denn mal den verlinkten Wikipedia-Artikel angesehen?
Ja, soeben. Vielen Dank das könnte ja schon die Lösung sein.

Viele Grüße

von Dennis S. (eltio)


Lesenswert?

Dennis S. schrieb:
> https://de.wikipedia.org/wiki/Unixzeit#Jahr-2038-Problem

Was mich bei der Beispielimplementierung wundert: über dem Quellcode 
steht "Das Jahr-2038-Problem tritt bei diesem Programm jedoch nicht auf 
[...]". Trotzdem ist der Gültigkeitsbereich für das Jahr mit 
[1970..2038] angegeben. Wie passt das zusammen?

von Bauform B. (bauformb)


Lesenswert?

Das ist doch nur ein Kommentar in einer C-Quelle. Man sieht, ein 
veralteter Kommentar ist schlechter als garkeiner.
1
"Wie jeder Beispielquelltext dient er allein der Illustration"
nämlich, welche Fehler bei der Umstellung 32/64 Bit passieren können.

Außerdem kann man daraus lernen, dass man nicht alles glauben sollte, 
was man im Internet findet. Besonders, wenn es C-Kommentar ist.


Für kleine Rechner war ein Timestamp aus 2 Teilen sehr beliebt (weil, 
immer noch besser als 6). Also das Datum als ein 16-Bit Wert ("Modified 
Julian Date") und dazu die Zeit, je nach nötiger Auflösung einmal oder 
zweimal 16 Bit. Das entspricht der Unixtime geteilt durch 86400 + 
Offset.

Auf einem 8-Bit uC habe ich mal zwei 24-Bit Werte verwendet und hatte 
dann 25ms Auflösung und einen Kalender, der "nur" bis 3200 geht, weil 
noch nicht festgelegt ist, ob das ein Schaltjahr ist. Die Kommentare 
sind komplett groß geschrieben, weil das Terminal noch keine 
Kleinbuchstaben konnte. Das waren noch Zeiten :)
1
;       0    1-JAN-4713   ERSTER TAG IM AKTUELLEN SCALIGER-ZYKLUS
2
;            1-JAN-45     OFFIZIELLER BEGINN DES JULIANISCHEN KALENDERS
3
;       -----------
4
;           29-FEB-8      ERSTER REGELMAESSIGER(!) SCHALTTAG
5
; 2299160    4-OKT-1582   ENDE DES JUL. KAL.
6
; 2299161   15-OKT-1582   BEGINN DES GREGORIANISCHEN KALENDERS
7
; 2400001   17-NOV-1858   TAG 0 DES MODIFIED JULIAN DATE
8
; 2889895   29-FEB-3200   EVT. KEIN SCHALTTAG (-> 21-JAN-3268)
9
; 2914694   22-JAN-3268   LETZTER TAG IN DIESEM SCALIGER-ZYKLUS

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.