Std ist Müll



  • Hi, seit einer geschlagen Stunde versuche ich den UTC Offset mit diesen verfrickelten Std Aufrufen zu berechnen was ja wohl in einer vernünftigen Programmiersprache eine Sache von 1 Minute sein sollte. Warum geht diese Schei...e nicht? Und das beste! Kommentiere ich die beiden Zeilen des Test Printouts wieder rein wird bei den anderen Printouts statt wie sonst die UTC die local Time angezeigt. Was zur Hölle ist da los?

    int GetUtcOffset() const
    {
    	std::time_t rawTime = std::time(nullptr);
    	struct std::tm* systemTimeInfo = std::gmtime(&rawTime);
    	std::time_t rawTime2 = std::time(nullptr);
    	struct std::tm* localTimeInfo = std::localtime(&rawTime2);
    
    	//time_t t = time(nullptr);
    	//printf("Test:       '%s'\n", asctime(gmtime(&t)));
    
    	printf("UTC:       '%s'\n", asctime(systemTimeInfo));
    	printf("Local:     '%s'\n", asctime(localTimeInfo));
    	int offset = static_cast<int>(difftime(rawTime2, rawTime));
    	return offset;
    }
    

    So eine völlig fehldesignte Schei.. raubt einem echt den letzten Nerv.



  • Du hast doch mit localtime schon die richtige Funktion gefunden. Hast du überhaupt mal nachgeguckt, was ein std::tm so an Feldern hat? Zum Beipiel tm_gmtoff?

    Allgemein sind bei allen Datum/Zeit-Fragen Howard Hinnants Klassen sehr hilfreich. Aber hier ist es doch ein Zweizeiler.

    Edit: oops, tm_gmtoff scheint nicht auf allen Plattformen verfügbar zu sein - ist eine Erweiterung. Bei mir gehts 🙂



  • Dir ist aber schon klar, dass std::time (vermutlich ctime includiert) keine c++ api ist sonder einfach die c-api ist, die in den std namespace befördert wurde?
    gmtime und localtime liefern einen pointer auf eine tm struct zurück, die intern von der API verwaltet wird.
    Und zwar verwenden beide funktionen die selbe instanz.

    http://www.cplusplus.com/reference/ctime/localtime/

    he returned value points to an internal object whose validity or value may be altered by any subsequent call to gmtime or localtime.

    Eine c++/std api wäre die std::chrono api

    @wob Wo hat die std::tm struktur ein feld namens tm_gmtoff? Laut https://en.cppreference.com/w/cpp/chrono/c/tm gibt es diesen member nicht.



  • localtime sagt:

    The returned value points to an internal object whose validity or value may be altered by any subsequent call to gmtime or localtime.

    #include <ctime>
    #include <iostream>
    
    int GetUtcOffset()
    {
    	std::time_t now{ std::time(nullptr) };
    	std::tm gm_time{ *std::gmtime(&now) };
    	std::tm local_time{ *std::localtime(&now) };
    	
    	return local_time.tm_hour - gm_time.tm_hour;
    }
    
    int main ()
    {
    	std::cout << GetUtcOffset() << '\n';
    }
    


  • Ja, tm_gmtoff ist eine Nicht-Standard-Erweiterung, siehe z.B. hier, sorry.

    std::chrono hat die TZ-Unterstützung wohl erst ab C++20, davor schaut man bei H.H. nach.

    @Swordfish: das geht so nicht. Was machst du mit Halbstunden-Zeitzonen? Was, wenn sich der Tag ändert?

    Was zu funktionieren scheint:

    std::time_t tt = std::time(nullptr);
    auto dst = localtime(&tt)->tm_isdst;
    auto utc = std::gmtime(&tt);
    // Sommerzeit-Einstellung ändern, ansonsten bekomme ich nur das
    // Offset ohne Sommerzeit
    utc->tm_isdst = dst;
    cout << (tt - mktime(utc)) / 60 << " Minuten Offset\n";
    

    Sieht kompliziert aus, wenn die tm_gmtoff-Erweiterung nicht verfügbar ist.



  • @wob sagte in Std ist Müll:

    Was machst du mit Halbstunden-Zeitzonen?

    Sachen gibts 😲

    @wob sagte in Std ist Müll:

    Was, wenn sich der Tag ändert?

    Übungsaufgabe für nachfolgende Generationen 😉



  • @swordfish sagte in Std ist Müll:

    Sachen gibts

    Siehe https://www.tagesschau.de/ausland/nordkorea-suedkorea-115.html - ich weiß nicht, ob es aktuell noch was "unganzstundiges" gibt 🙂 Es kann immer mal Dikatoren geben, die eine Spezialzeit brauchen!



  • So ich habe mich abgeregt. Der time_t Datentyp ist doch intern "im Prinzip" nur ein "long"? wo die Sekunden seit dem 01.01.1970 00:00:00 UTC drin stehen. Also müsste ich doch die Differenz in Sekunden bekommen wenn ich die utc von der localtime substrahiere (difftime) oder wo ist mein Denkfehler? Wer kann mir denn sagen was jetzt genau an dem Code vom ersten Posting falsch ist? Ich würde diesen Murks wenigstens gerne verstehen.



  • @firefly sagte in Std ist Müll:

    gmtime und localtime liefern einen pointer auf eine tm struct zurück, die intern von der API verwaltet wird.
    Und zwar verwenden beide funktionen die selbe instanz.
    .
    http://www.cplusplus.com/reference/ctime/localtime/
    The returned value points to an internal object whose validity or value may be altered by any subsequent call to gmtime or localtime.

    @swordfish sagte in Std ist Müll:

    localtime sagt:
    The returned value points to an internal object whose validity or value may be altered by any subsequent call to gmtime or localtime.



  • This post is deleted!


  • Würde mich wundern wenn es die selbe Instanz ist. Ich habe ja deswegen extra ein rawTime2 angelegt, was natürlich auch blöd ist...
    Gibt es nicht unter Linux ein äquivalent zum gettimeofday das die localtime zurückgibt? Oder die Möglichkeit unter Linux direkt den Offset abzufragen. Diesen Std Müll möchte ich gar nicht verwenden...



  • @enumerator sagte in Std ist Müll:

    Würde mich wundern wenn es die selbe Instanz ist. Ich habe ja deswegen extra ein rawTime2 angelegt

    Was soll das für einen Einfluss darauf haben, worauf die von std::gmtime() und std::localtime() zurückgegebenen Zeiger verweisen? Nochmal:

    The returned value points to an internal object whose validity or value may be altered by any subsequent call to gmtime or localtime.



  • Als alternative zu localtime/gmtime gibt die varianten mit _r postfix. Die füllen eine übergebene tm struktur mit den Daten.
    Dadurch spart man sich die kopie wie bei @Swordfish Beispiel. Ein weiterer Vorteil der *_r varianten ist die, das diese threadsafe sind.



  • @wob sagte in Std ist Müll:

    ich weiß nicht, ob es aktuell noch was "unganzstundiges" gibt

    Indien?







  • Australien ist auch ein super Beispiel, insbesondere wegen der Unterschiede Sommer/Winter. Es gibt auch noch andere spannende Zeitzonen wie Nepal (UTC +5:45) oder die +14 Stunden von Line Islands Time.



  • @wob sagte in Std ist Müll:

    spannende Zeitzonen

    Wow, bist Du leicht zu unterhalten.


Log in to reply