pl: C time.h localtime

Mal wieder eine Sache die ich nicht verstehe, Code:

    // Zeit vom Zeitserver
    const time_t time = htonl(v) - 2208988800;

    // struct tm *localtime(const time_t *zeitzeiger);
    // struct tm *gmtime(const time_t *zeitzeiger);
    struct tm *date, *gmt;
    date = localtime(&time);
    gmt  = gmtime(&time);  // es geht um diese Zeile

    puts("Aktuell vom Zeitserver");
    puts("======================");
    printf("Sekunden seit 1.1.1970: %u\n", time);
    printf("Datum und Uhrzeit: %02d.%02d.%04d %02d:%02d:%02d\n",
        date->tm_mday, date->tm_mon + 1, date->tm_year + 1900,
        date->tm_hour, date->tm_min, date->tm_sec
    );
    printf("Sommerzeit, DST: %s\n", date->tm_isdst == 0 ? "Nein" : "Ja" );

Es geht um die Zeile gmt = gmtime(&time); an dieser Stelle angewiesen steht in date komischerweise auch eine GMT. Weise ich gmt = gmtime(&time); nach dem printf(..) an, sehe ich auch die Localtime.

Wie ist das zu verstehen?

  1. Moin,

    Mal wieder eine Sache die ich nicht verstehe, Code:

    dito – meine Begründung, was ich nicht verstehe kommt unten.

        // Zeit vom Zeitserver
        const time_t time = htonl(v) - 2208988800;
    

    (Natürlich kann man eine lokale Variable wie eine globale Funktion nennen, aber es verwirrt nur unnötig.)

        // struct tm *localtime(const time_t *zeitzeiger);
        // struct tm *gmtime(const time_t *zeitzeiger);
        struct tm *date, *gmt;
        date = localtime(&time);
        gmt  = gmtime(&time);  // es geht um diese Zeile
    

    Es geht um die Zeile gmt = gmtime(&time); an dieser Stelle angewiesen steht in date komischerweise auch eine GMT. Weise ich gmt = gmtime(&time); nach dem printf(..) an, sehe ich auch die Localtime.

    Wie ist das zu verstehen?

    Dass du wiederholt nicht die Dokumentation der C-Standard-Bibliothek liest. Über localtime steht dort:

    Return value

    pointer to a static internal tm object on success, or null pointer otherwise. The structure may be shared between gmtime, localtime, and ctime and may be overwritten on each invocation.

    Viele Grüße
    Robert

    1. Achso, may be shared, is ja listig 😉

      Danke Dir!

      Dasselbe in Perl

      1. Achso, may be shared, is ja listig 😉

        Auf den von mit benutzten Seiten zur libc steht übrigens nichts von shared!

        Danke Dir!

        Dasselbe in Perl

        1. Moin,

          Auf den von mit benutzten Seiten zur libc steht übrigens nichts von shared!

          Welche Seiten sind das? Wenn ich eine Linux-Dokumentation zu localtime heranziehe, steht auch dort:

          The gmtime() function converts the calendar time timep to broken-down time representation, expressed in Coordinated Universal Time (UTC). It may return NULL when the year does not fit into an integer. The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions.

          The localtime() function converts the calendar time timep to broken-down time representation, expressed relative to the user's specified timezone. […] The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions.

          Viele Grüße
          Robert

          1. Das Verhalten war mir neu. Da macht es ja überhaupt keinen Sinn 2 ober mehrere Variablen vom selben Type zu deklarieren. Schlechtes Beispiel auch was ich da gefunden hab.

            MfG

            1. Hallo pl,

              was meinst du genau?

              Viele Grüße
              Robert

              1. moin,

                stell Dir vor Du arbeitest mit mehreren Zeit-Objekten. Chaotischer gehts nicht: Beim Aufruf einer Methode werden alle Deine Instanzen geändert. Nee, da schreib ich mir doch lieber gleich eine eigene Lib wo sowas nicht passiert.

                    SCA *sca = scaliger_date(2299160);
                    printf("%c %d %d.%d.%d %d\n",
                        sca->age, sca->jd, sca->day, sca->month, sca->year, sca->wd
                    ); // J 2299160 4.10.1582 4
                

                War sowieso längst überfällig. add(sca) ändert nur diese Instanz. MfG

                1. Moin,

                  stell dir vor, eine Bibliothek bietet dir Funktionen um Objekte zu kopieren …

                  Viele Grüße
                  Robert

                  1. stell dir vor, eine Bibliothek bietet dir Funktionen um Objekte zu kopieren …

                    Kopieren ist nicht meine Art!

                        SCA *sca = scaliger_day( '?', 4, 10, 1582 );
                        //SCA *sca = scaliger_date(2299160);
                        //sca = scaliger_time(1548496083); // since 1.1.1970
                    
                        sca = adddays(sca, 1);
                        printf("Age: %c\nJD: %d\nDate: %d.%d.%d\nWD: %d\nTime: %d:%d:%d\nLeap: %d",
                            sca->age, sca->jd, sca->day, sca->month, sca->year, sca->wd,
                            sca->hour, sca->minute, sca->second, sca->leap
                        );
                    
                    
                    Ausgabe:
                    
                    Age: G
                    JD: 2299161
                    Date: 15.10.1582
                    WD: 5
                    Time: 0:0:0
                    Leap: 0
                    

                    So läuft das bei mir und wie gesagt, das steht schon lange aufm Plan.

                    MfG

        2. Hallo pl,

          in der Doku von GCC LIBC steht:

          Using the localtime function is a big problem in multi-threaded programs. The result is returned in a static buffer and this is used in all threads. POSIX.1c introduced a variant of this function.

          Und dahinter stehen die localtime_r und gmtime_r Funktionen, die mit einem von Dir übergebenen Buffer statt dem statischen Buffer arbeiten.

          Welchen C-Compiler nutzt Du? Bietet der auch sowas?

          Rolf

          --
          sumpsi - posui - clusi
          1. Hallo Rolf,

            Und dahinter stehen die localtime_r und gmtime_r Funktionen, die mit einem von Dir übergebenen Buffer statt dem statischen Buffer arbeiten.

            Die standardisierten Varianten ab C11 heißen fast genau, einfach _r durch _s ersetzen: https://en.cppreference.com/w/c/chrono/localtime

            Viele Grüße
            Robert