Arbeiten mit Unix-Timestamp

T_55

Lieutenant
Registriert
Feb. 2013
Beiträge
638
Hallo,

es wird mal Zeit sich mit selbiger also der Zeit in C++ zu beschäftigen, wovon ich wie ich feststellen musste noch gar keine Ahnung habe.

Welcher Datentyp ist am besten zur Speicherung von Unix-Timestamp Datenreihen (Sekunden ab 1970) damit es, egal wie kompiliert (32 sowie 64 bit), kein Jahr-2038-Problem entsteht?
Sicherheitshalber hab ich mal std::vector<unsigned long long> genommen um auf der sicheren Seite zu sein.

Wie kann man aus dem gespeicherten Zeitwert den Wochentag, Stunde und Minute rausfinden? Ich möchte in einer Zeitabfolgesimulation mit Temperaturdaten, beim durchlaufen von bestimmten Zeitbereichen ein bool aktivieren. Der vector mit den Zeitwerten wird also durchgeschleift und es soll dann zB jeden Dienstag um 13:35 ein bool auf true und Donnerstags um 23:02 auf false gestellt werden. Gibt es da vielleicht ein Ansatz?

Grüße
 
Ich kann kein C++, sondern nur C. Möglicherweise bietet C++ bessere Alternativen an.

T_55 schrieb:
Welcher Datentyp ist am besten zur Speicherung von Unix-Timestamp Datenreihen (Sekunden ab 1970) damit es, egal wie kompiliert (32 sowie 64 bit), kein Jahr-2038-Problem entsteht?
time_t

Wie kann man aus dem gespeicherten Zeitwert den Wochentag, Stunde und Minute rausfinden? Ic
localtime()
 
Dafür solltest Du andere Funktionen benutzten, die direkt Datum und Uhrzeit liefern. Der Timestamp ist für so etwas ungeeignet und wäre zuviel Aufwand für eine simple Datums-/Zeitabfrage.
 
Danke das funktioniert gut!

Ich hätte nochmal eine Frage zur Logik um einen Zeitabschnitt zu identifizieren.
Man könnte wenn man gesammelte Zeitdaten durchlaufen lässt prüfen ob die Bedingungen von Wochentag, Stunde und Minute mit den übereinstimmen die das bool auf false oder true setzen sollen. Jetzt ist es aber so, dass die gesammelten Zeitdaten zB aus einer Datenbank wo Zeit und Temperatur gespeichert werden, unvollständig sein könnten. Wenn nun genau in der Minute keine Daten vorhanden sind funktioniert also der einfache Abgleich nicht mehr obwohl der Zeitraum dann gültig wäre.
Hat jemand eine Idee wie man einen Zeitabschnitt identifiziert ohne das Start und Enddatum Punktgenau in der Datenbank vorhanden sein müssen (was eben passieren kann)?

Gruß
 
Du rechnest deine Anfangszeit in einen Timestamp um. Dann suchst du via SELECT alle timestamp Werte die größer sind aber lässt den SELECT Befehl nur den ersten, kleinsten zurückgeben. Das ist der erste Wert in deinem Zeitintervall. Für die Endzeit machst du das Analog
Damit hast du Anfang und Ende, die ID der jeweiligen Zeiten (deine Tabelle hat eine fortlaufende ID, primary key, etc?). Also nur noch alle Werte zwischen den beiden IDs ausgeben lassen.
 
Zur Zeit hab ich noch gar keine Datenbank (kommt aber noch) sondern teste per vector<time_t>
Ich habs noch nicht ganz verstanden denn der Anfangswert des Zeitabschnittes ist doch jede Woche ein anderer.
Ist der Zeitpunkt der durch Wochentag, Stunde und Minute abgeglichen wird nicht in der Datenreihe vorhanden, wird das bool nicht korrekt aktiviert.

Code:
bool zeitabschnittaktiv = false;

std::vector<time_t> zeitwert;

struct tm *tmnow = zeitwert[iterierte];

// von dienstag 13:48 Uhr
int start_wday = 2, start_hour = 13, start_min = 48;

// bis freitag 06:22 uhr
int end_wday = 5, end_hour = 6, end_min = 22;

/*
tmnow->tm_hour
tmnow->tm_min
tmnow->tm_wday
*/
Ergänzung ()

Glaube so geht es: Man muss checken ob die Werte aus tm_hour, tm_min und tm_wday größer/gleich die von start_hour, start_min und start_wday sind. Und kleiner/gleich für die endwerte.
 
Ich hoffe bei 4. füllst du den vektor bevor du darauf (wie in Zeile 5) zugreifst?
Ansonsten würde ich generell QDateTime vorziehen..
Wie willst du mit Zeitzonen umgehen?
 
jo das war nur Beispielhaft die Daten müssen natürlich rein. Zeitzone ist erstmal die, woher die Daten kommen, worin auch die Zeit gespeichert ist. Für QDateTime müsste ich das in QT machen, wäre ne Möglichkeit.
Ich überlege aber ob ich das mit der Sommerzeit einbeziehe bzw wenn sie in den Daten steckt sie dann zur Winterzeit zu korrigieren (tm_isdst>0) denn irgendwie verfälscht man damit die Vergleichbarkeit der Werte wenn 2x im Jahr die Stunde verspringt. Am besten sind die Daten gleich immer als UTC abgelegt sonst ist Zeit wirklich sehr relativ :)
 
Warum nicht std::chrono::seconds? Ist auf allen Platformen (x86, x64, arm, arm64 etc) groß genug um mindestens ±292 Jahre abzudecken.

Wie du schon richtig gesagt hast sollte man intern immer mit "<Zeiteinheit>-since-epoch" rechnen. Wenn du aber für die Darstellung ein Datumsformat benötigst kann ich die Date Bibliothek von HowardHinnant empfehlen (die kümmert sich bei bedarf auch um Zeitzonenkonvertierungen).
 
Steht einem denn mit chrono auch sowas wie struct tm zu Verfügung?

T_55 schrieb:
Man muss checken ob die Werte aus tm_hour, tm_min und tm_wday größer/gleich die von start_hour, start_min und start_wday sind. Und kleiner/gleich für die endwerte.

Damit lag ich Falsch, es kann ja nur Tag bis Tag oder Stunde bis Stunde etc geprüft werden aber nicht von Tag 3, Stunde 15, Minute 7 bis Tag 5, Stunde 10, Minute 30. Also folgende zwei Logiken bekomme ich nicht hin:

- Anhand von Unixwert feststellen ob man sich innerhalb von Zeitspanne von Tag/Std/Min bis Tag/Std/Min befindet
und
- Anhand von Unixwert feststellen ob man sich innerhalb von Zeitspanne von Std/Min bis Std/Min befindet

:confused_alt:
Ergänzung ()

Es sieht so aus als wäre mktime dafür geeignet:
Direkt ausprobiert aber wday stimmt leider nicht. Das Problem scheint, dass tm_wday und tm_yday in der tm-Struktur ignoriert wird (https://www.proggen.org/doku.php?id=c:lib:time:mktime).

Jetzt hatte ich mich schon gefreut aber das mit wday macht mein Code natürlich vollkommen unbrauchbar. Hat jemand eine Idee was man da machen kann?

tmEND->tm_wday und tmSTART->tm_wday ist immer 1 obwohl es 0 und 5 sein müsste.

Code:
    int start_wday = 0, start_hour = 5, start_min = 15;
    int end_wday = 5, end_hour = 15, end_min = 30;

    struct tm *tmnow;
    time_t aktuellezeit = time(NULL);
    tmnow = localtime(&aktuellezeit);
    std::cout << "Zeitwert  =" << aktuellezeit <<" wday=" << tmnow->tm_wday <<" hour=" << tmnow->tm_hour <<" min=" << tmnow->tm_min <<  "\n";

    struct tm *tmSTART;
    tmSTART = localtime(&aktuellezeit);
    tmSTART->tm_wday = start_wday;
    tmSTART->tm_hour = start_hour;
    tmSTART->tm_min = start_min;
    time_t startwert = mktime(tmSTART);
    std::cout << "Startwert =" << startwert <<" wday=" << tmSTART->tm_wday <<" hour=" << tmSTART->tm_hour <<" min=" << tmSTART->tm_min <<  "\n";

    struct tm *tmEND;
    tmEND = localtime(&aktuellezeit);
    tmEND->tm_wday = end_wday;
    tmEND->tm_hour = end_hour;
    tmEND->tm_min = end_min;
    time_t endwert = mktime(tmEND);
    std::cout << "Endwert   =" << endwert <<" wday=" << tmEND->tm_wday <<" hour=" << tmEND->tm_hour <<" min=" << tmEND->tm_min <<  "\n";
Ergänzung ()

Habe eine Lösung entwickelt: Vielleicht nicht so schick aber funktioniert

Code:
    int start_wday = 0, start_hour = 23, start_min = 15;
    int end_wday = 5, end_hour = 10, end_min = 55;

    struct tm *tmnow;
    time_t aktuellezeit = time(NULL);
    tmnow = localtime(&aktuellezeit);
    std::cout << "Zeitwert  =" << aktuellezeit <<" wday=" << tmnow->tm_wday <<" hour=" << tmnow->tm_hour <<" min=" << tmnow->tm_min <<  "\n";

    struct tm *tmSTART;
    tmSTART = localtime(&aktuellezeit);
    tmSTART->tm_hour = start_hour;
    tmSTART->tm_min = start_min;
    time_t startwert = mktime(tmSTART);
    if(tmnow->tm_wday > start_wday) 
    {
        startwert = startwert - ((tmnow->tm_wday - start_wday)*86400);
    }
    if(tmnow->tm_wday < start_wday) 
    {
        startwert = startwert + ((start_wday - tmnow->tm_wday)*86400);
    }
    tmSTART = localtime(&startwert);
    std::cout << "Startwert =" << startwert <<" wday=" << tmSTART->tm_wday <<" hour=" << tmSTART->tm_hour <<" min=" << tmSTART->tm_min <<  "\n";

    struct tm *tmEND;
    tmEND = localtime(&aktuellezeit);
    tmEND->tm_hour = end_hour;
    tmEND->tm_min = end_min;
    time_t endwert = mktime(tmEND);
    if(tmnow->tm_wday > end_wday)
    {
        endwert = endwert - ((tmnow->tm_wday - end_wday)*86400);
    }
    if(tmnow->tm_wday < end_wday)
    {
        endwert = endwert + ((end_wday - tmnow->tm_wday)*86400);
    }
    tmEND = localtime(&endwert);
    std::cout << "Endwert   =" << endwert <<" wday=" << tmEND->tm_wday <<" hour=" << tmEND->tm_hour <<" min=" << tmEND->tm_min <<  "\n";
 
Zuletzt bearbeitet:
Zurück
Oben